예를 들어 다음은 파일의 내용입니다.
$ cat file
Name=Tom
Value=10
Name=Tom
Name=Harry
Value=20
이름 뒤에 값이 표시되지 않는 경우도 있습니다. 따라서 내가 해야 할 일은 Name=Tom 패턴을 찾아서 값을 바꾸는 것입니다. 단, 이름 바로 다음 줄에 나타나는 경우에만 해당됩니다. 어떻게 하나요?
답변1
그리고 awk
:
awk 'prev ~ /^Name=(Tom|Anything)$/ && /^Value=/ {$0 = "Value=123"}
{print; prev = $0}'
또는 이름그리고 새로운값변수에 저장:
export NAME=Tom VALUE=123
awk 'prev == "Name=" ENVIRON["NAME"] && /^Value=/ {
$0 = "Value=" ENVIRON["VALUE"]
}
{print; prev = $0}'
의 경우 sed
해당 내용은 다음과 같습니다.
sed -e 'x;/^Name=Tom$/{g;/^Value/s/=.*/=123/;h;b' -e '}' -e g
항상 그렇듯이 awk
. 또한 변수에 저장된 임의의 값을 처리하기 위해 's 와 동일한 기능도 sed
없고 간단한 문자열 비교를 수행하는 기능도 없습니다(정규식 일치와 반대). 변수에 .awk
ENVIRON
sed
sed -e "x;/^Name=$NAME\$/{g;/^Value/s/=.*/=$VALUE/;h;b" -e '}' -e g
및 가 엄격하게 제어되지 않으면 명령 주입 취약점이 됩니다(적어도 GNU의 경우 sed
).$NAME
$VALUE
답변2
더 컴팩트하고 간단해졌습니다.
sed 'G;/^Value=/s/=.*\nName=Tom/=42/;s/\n.*//;h' file
이렇게 하면 예약된 공간의 이전 행이 각 행에 추가됩니다. 행의 경우 값이 예약된 공간에 있으면 Value=
값이 대체됩니다. Name=Tom
그렇지 않으면 추가된 행이 제거되고 해당 행은 다음 주기를 위해 예약된 공간에 저장됩니다.
답변3
sed -e '
/^Name=Tom$/!b
$!N
/\(\nValue\)=.*/s//\1=NEW_VALUE/
P;D
' data.inp
설명하다
- Tom이라는 이름이 포함된 행을 찾습니다. 불일치는 표준 출력으로 전달됩니다.
- 그런 다음 마지막 줄이 아닌 경우 패턴 공간에 다음 줄을 추가하려고 시도합니다.
- 방금 추가한 줄에서 정규식 Value=를 찾고, 그렇다면 값이 NEW_VALUE로 변경됩니다(필요한 대로 변경해야 합니다).
- P;D =>는 Name=Tom 바로 앞 줄인\n 왼쪽에 패턴 공간 부분을 인쇄한 다음 해당 부분을 삭제합니다. 이제 Value=NEW_VALUE가 남았으므로 sed 스크립트 줄의 시작 부분으로 이동합니다. /^Name=Tom$/!b 분명히 이 작업은 실패하므로 표준 출력으로 이동됩니다. 이는 연속적인 Name=Tom 행을 처리하기 위해 수행됩니다.
결과
Name=Tom
Value=NEW_VALUE
Name=Tom
Name=Harry
Value=20