라인의 값을 바꾸는 방법은 무엇입니까?

라인의 값을 바꾸는 방법은 무엇입니까?

값이 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또는 레이블이 지정되지 않은 경우 스크립트 끝) 로 분기됩니다.seds

이 경우 첫 번째 대체가 이루어지면 두 번째 대체가 무시됩니다.


online=YESonline=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=NO1YESYES1\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//'

관련 정보