그래서 이런 파일이 있어요
[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
에만 적용됩니다 .startregex
stopregex
이 경우 시작 정규식은 입니다 /\[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