다음 내용을 포함하는 파일이 제공됩니다.
pkg1:
replicaCount: 1
image:
tag: latest
pullPolicy: Always
pkg2:
replicaCount: 2
image:
tag: latest
pullPolicy: Always
tag
특정 패키지(예: )에 추가된 내용을 검색 하고 다른 패키지(예: )로 pkg1
바꾸면 다음과 같은 결과를 얻을 수 있습니다.latest
junk
pkg1:
replicaCount: 1
image:
tag: junk
pullPolicy: Always
pkg2:
replicaCount: 2
image:
tag: latest
pullPolicy: Always
이 게시물에 대한 답변에 감사드립니다(문자열을 찾고 첫 번째 문자열을 찾은 후 다른 문자열을 바꿉니다.) "ex"를 사용하여 이 작업을 수행할 수 있습니다.
printf "%s\n" "/pkg1//latest/s//junk/" x | ex info.txt;
그런데 문제는 "ex"가 없는 이미지에서 실행된다는 점이다.
"awk"로 이 작업을 수행할 수 있는 방법이 있나요? 나는 파일을 한 줄씩 읽고 그런 식으로 일부 작업을 수행할 수 있다고 생각하지만 더 쉬운 방법을 찾고 있었습니다. 한 줄이라면 문제가 없습니다. 이것이 첫 번째 발생인지 두 번째 발생인지 항상 가정할 수는 없습니다. 그래서 패키지 이름을 검색해서 해당 패키지의 태그만 교체하면 됩니다.
답변1
가장 쉬운 방법은 명령줄 YAML 파서를 사용하는 것입니다.
$ yq -y '.pkg1.image.tag |= "junk"' file
pkg1:
replicaCount: 1
image:
tag: junk
pullPolicy: Always
pkg2:
replicaCount: 2
image:
tag: latest
pullPolicy: Always
나는 그것을 사용하고 있습니다 yq
,Andrei Kislyuk jq
YAML 문서 래퍼(다른 도구 yq
도 호출되므로 올바른 도구를 사용하는지 확인하세요.)
이 명령은 .pkg1.image.tag
키 값을 string 으로 설정하고 junk
, 이 -y
옵션은 기본 JSON 대신 YAML 출력을 생성하는 데 사용됩니다.
yq
나는 이것이 Debian 기반 Linux 배포판의 기본값이라고 생각합니다 . YAML 문서를 JSON으로 변환하고 jq
다음을 사용하여 수정해야 합니다.
$ yq r -j file.yml | jq '.pkg1.image.tag |= "junk"' | yq r -P -
pkg1:
replicaCount: 1
image:
tag: junk
pullPolicy: Always
pkg2:
replicaCount: 2
image:
tag: latest
pullPolicy: Always
답변2
가능한 경우 perl
:
PKG=pkg1 FIELD=tag VALUE=junk perl -pi -e '
$pkg = $1 if /^(\S.*?)\s*:\s*$/;
s/^\s+\Q$ENV{FIELD}\E\s*:\s*\K.*/$ENV{VALUE}/ if $pkg eq $ENV{PKG}' -- "$file"
최신 버전의 GNU 구현을 제외하고 awk
파일의 내부 편집은 지원되지 않습니다 . 실제로 최근에 멍청한 사람 이라면 awk
위와 동일한 작업을 수행할 수 있습니다.
PKG=pkg1 FIELD=tag VALUE=junk gawk -i /usr/share/awk/inplace.awk -e '
match($0, /^([^[:space:]](.*[^[:space:]])?)[[:space:]]*:[[:space:]]*$/, f) {
pkg = f[1] ""
}
pkg == ENVIRON["PKG"] {
$0 = gensub("^([[:space:]]+"ENVIRON["FIELD"]"[[:space:]]*:[[:space:]]*).*", \
"\\1" ENVIRON["VALUE"], 1)
}
{print}' -E /dev/null "$file"
awk
저는 API 의 몇 가지 제한 사항과 주의 사항을 해결하려고 노력합니다 awk
.
-v var=value
맹글 백슬래시 방법을 사용하여 매개변수를 환경 변수로 전달합니다.pkg = f[i] ""
: 비교가 항상 문자열 비교인지 확인하기 위해""
문자열로 처리되도록 a를 추가합니다( 아니요 대).pkg
awk
==
eq
perl
-e 'code' -E /dev/null "$file"
(GNU 확장) 임의의 파일 이름을 처리하는 데 필요합니다.
하지만 일부 남아 있는 부분이 있는데, 이는 특정 입력에 대한 특수한 경우에는 여전히 제대로 작동하지 않는다는 것을 의미합니다.
perl
/ 와 동등한 것이 없으므로\Q
awk 정규식 연산자(char)를 포함하면\E
작동하지 않습니다.FIELD
.^${}[]\?+*|
VALUE
대체 매개변수에서 또는 포함&
문자가 특별히 처리 되면\
올바르게 작동하지 않습니다 .gawk
gensub()
^사용하지 마세요-i inplace
현재 작업 디렉터리(as or)에서 확장 기능을 먼저 gawk
로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'