설명하다:

설명하다:

그래서 이런 파일이 있어요

[ABC]
value1=bla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla

[ABC] 블록 아래의 value1을 [XYZ] 블록 아래의 value1 대신 "value1=notbla"로 바꾸고 싶습니다. 난 이미 시도했어

sed '/ABC/{n;s/.*/change/}'  file

그러나 이것은 다음 줄로 이동하려고 할 때만 작동하며 특정 패턴을 변경하지 않습니다(예: value1이 value2보다 낮은 경우). 특정 줄 번호를 모르는 경우 어떤 sed 또는 awk 명령을 사용할 수 있습니까? 사용된 각 sed 또는 awk 태그의 기능을 표시할 수 있습니까? 진심으로 감사드립니다.

답변1

sed는 이를 쉽게 처리할 수 있습니다. 이는 주소 범위가 접두어로 붙는 단일 "교체" 명령입니다. 가독성을 높이기 위해 추가 간격을 추가했습니다.

sed -e '/^\[ABC\]$/ , /^\[.*\]$/     s/^\(value1=\).*$/\1notbla/'

추가 간격이 없으면 다음과 같습니다.

sed -e '/^\[ABC\]$/,/^\[.*\]$/s/^\(value1=\).*$/\1notbla/'

실제로 정규식을 고정할 필요는 없지만 비정상적인 입력이 있는 특정 경우에는 더 안전할 수 있습니다. 고정되지 않은 정규식을 사용하는 약간 더 짧은 버전은 다음과 같습니다.

sed -e '/\[ABC\]/,/^\[/s/^\(value1=\).*$/\1notbla/'

설명하다:

각 플래그나 옵션에 대한 설명을 요청하셨는데 시간이 있으니 이쯤 하겠습니다. 위에 나열된 세 가지 Sed 명령의 최종(가장 짧은) 버전을 설명하고 있습니다.

행의 첫 번째 부분은 주소 범위입니다. 주소 범위 뒤의 대체 /startregex/,/stopregex/ 명령은 ~ 부터(포함)까지의 행 s에만 적용됩니다 .startregexstopregex

이 경우 시작 정규식은 입니다 /\[ABC\]/. 대괄호는 일반적으로 정규식의 특수 문자이므로 리터럴 대괄호 문자를 나타내기 위해 각 문자 앞에 백슬래시를 추가합니다.

정규식을 중지한다는 것은 /^\[/특수 정규식 문자를 사용하여 ^줄의 시작을 표시한다는 것입니다. 이 패턴은 [여는 괄호( )로 시작하는 모든 줄과 일치합니다 .

대체 명령은 s기본적으로 매우 간단합니다. 일반적인 형식은 입니다 s/findregex/replacetext/. 또한 동작을 수정하기 위해 Final 뒤에 특수 플래그를 넣을 수도 있지만 /여기서는 그러한 플래그를 사용하지 않았습니다.

"정규식 찾기"는 입니다 ^\(value1=\).*$.

^앞서 언급했듯이 캐럿( )은 줄의 시작 부분과 일치하고 달러 기호( $)는 줄의 끝 부분과 일치합니다. 따라서 전체 패턴은 라인의 일부가 아닌 전체 라인과 일치해야 합니다.

()대괄호( )는 대괄호와 달리아니요-special은 기본적으로 정규식에서 특별하므로 특별한 의미를 부여하기 위해 백슬래시를 앞에 추가합니다. 부분 일치 텍스트(정규식 찾기와 일치하는 텍스트)를 대체 텍스트에 사용할 수 있습니다. 특히 \1텍스트에서 바꾸기는 "정규식의 첫 번째 대괄호 세트 내에서 일치하는 텍스트"를 의미합니다. 이 경우에는 항상 "value1="입니다.

"정규식 찾기"의 마지막 요소는 입니다 .*. 점( .)은 "모든 단일 문자"를 의미하고 별표( *)는 "임의의 횟수(0개 이상)"를 의미합니다. 따라서 점선 별표( .*)는 등호 뒤의 나머지 줄 전체와 일치합니다.

대체 텍스트의 "notbla"는 특별한 내용이 아닌 정적 텍스트일 뿐입니다.


Sed를 제대로 배우려면 강력히 추천합니다Grymoire Sed 튜토리얼, 온라인에서 무료입니다.

답변2

awk '
  BEGIN {FS=OFS="=";}
  /\[.*\]/ {if ($0 == "[ABC]") edit=1; else edit=0;}
  {if (edit && $1 == "value1" ) $2="notbla";}1
' file 

답변3

또 다른 awk솔루션

$ cat ip.txt 
[ABC]
value1=bla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla

행이 [지정된 플래그로 시작하는 경우 해당 플래그는 블록 이름에 따라 설정되거나 지워집니다. 그런 다음 플래그가 설정되면 교체하십시오.

$ awk '/^\[/{f=/\[ABC\]/} f{sub("value1=bla","value1=nobla")} 1' ip.txt 
[ABC]
value1=nobla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla


의 유사한 솔루션이 perl데모의 대안으로 변경되었습니다.

$ perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=bla/value2=nobla/ if $f;' ip.txt 
[ABC]
value1=bla
value2=nobla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla


=특정 일치 항목에 관계없이 오른쪽의 모든 항목을 변경해야 하는 경우 bla다음을 사용하세요.

awk '/^\[/{f=/\[ABC\]/} f{sub(/value1=.*/,"value1=nobla")} 1' ip.txt 
perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=.*/value2=nobla/ if $f;' ip.txt

관련 정보