
값이 yes YES
이면 실행하십시오 NO
. 그렇다면 그렇게 NO
하십시오 YES
. 예를 들어 다음 명령을 사용하고 있습니다.
( echo "online=YES"; echo "online=NO" ) | sed -e 's/online=YES/online=NO/' -e 's/online=NO/online=YES/'
online=YES
online=YES
첫 번째 패턴이 일치하면 두 번째 패턴을 건너뛰어야 합니다. 이는 next
의 와 동일합니다 awk
.
답변1
sed -e 's/online=YES/online=NO/' -e t -e 's/online=NO/online=YES/'
입력 행을 마지막으로 읽은 이후 이전 명령이 대체된 경우 의 t
명령은 지정된 레이블( sed
또는 레이블이 지정되지 않은 경우 스크립트 끝) 로 분기됩니다.sed
s
이 경우 첫 번째 대체가 이루어지면 두 번째 대체가 무시됩니다.
online=YES
online=NO
여러 행 또는 하나의 행이 있을 수 있는 경우에는 다음을 사용하세요.
sed -e 's/online=YES/online=MAYBE/g' \
-e 's/online=NO/online=YES/g' \
-e 's/online=MAYBE/online=NO/g'
여기서 문자열은 패턴과 연관 MAYBE
되지 않습니다 . online=
이는 임시 변수를 사용하여 두 변수의 값을 바꾸는 것과 본질적으로 유사합니다.
시험:
$ echo "online=YES online=YES online=NO online=YES" | sed -e 's/online=YES/online=MAYBE/g' -e 's/online=NO/online=YES/g' -e 's/online=MAYBE/online=NO/g'
online=NO online=NO online=YES online=NO
n
이 명령이 첫 번째 예의 명령을 완전히 대체하지 못하는 이유 t
는 이 명령이 스크립트 중간에 다음 입력 줄을 읽고 해당 줄에서 스크립트의 후반부를 실행하기 때문입니다.
$ ( echo "online=YES"; echo "online=YES" ) | sed -e 's/online=YES/online=NO/' -e n -e 's/online=NO/online=YES/'
online=NO
online=YES
동일한 출력이 두 줄 표시됩니다 NO
.
답변2
몇 가지 perl
팁:
perl -pe 's/online=\K(YES|NO)/$1 eq "YES" ? "NO" : "YES"/ge'
perl -pe 's/online=\K(YES(?{$r = "NO"})|NO(?{$r = "YES"}))/$r/g'
바라보다이 관련 질문에 대한 답변두 번째 예의 접근 방식을 일반화합니다.
여기서 해시를 사용하여 다음 단어에 적용할 번역 테이블을 정의할 수도 있습니다 online=
.
perl -pe 'BEGIN{%s = (YES => NO, NO => YES)}
s{online=\K\w+}{$s{$&} // $&}ge'
이전 솔루션과의 차이점은 ( 일치로 ) 확인하기 때문에 online=YES1
변경 되지 않는다는 것입니다 .online=NO1
YES
YES1
\w+
답변3
t
@Kusalananda가 지적한 명령을 사용하면 귀하의 예(및 대부분의 다른 예)에 적합합니다. 한 번에 두 문자열을 실제로 바꾸려면 다음과 같이 할 수 있습니다.
sed 'H;x;s/^/#NO#YES#NO/;s/.*#\(.*\)#\([^#]*\).*\n\(.*online=\)\1/\3\2/'
이는 회전을 위해 3개 이상의 스트링으로 쉽게 확장될 수 있습니다.
더 많은 행, 더 많은 대체가 있는 행 또는 전혀 대체가 없는 행을 처리하려면 이를 루프 대체로 확장할 수 있습니다.
sed -e 'H;x;s/online=/&#/g;s/^/#NO#YES#NO#/;:a' -e 's/\(.*#\)\(.*\)#\([^#]*\)\(#.*\n\)\(.*online=\)#\2/\1\2#\3\4\5\3/;ta' -e 's/.*\n//'