텍스트 파일의 특정 그룹의 합계를 변경하고 싶습니다 PATH
.LOC_NAME
예를 들어:
[a]
PATH=/tmp
SUR=Y
LOC_NAME=USA
[b]
PATH=/tmp
SUR=N
LOC_NAME=UK
따라서 검색하려면 [b]
그 이후의 첫 번째 일치 항목만 변경하고 싶습니다(다음 대신 다음 항목 이후 [*]
).
sed -i '/PATH/c\PATH=\/u01'
sed -i '/LOC_NAME/c\LOC_NAME=RUS'
답변1
당신은 매우 가깝습니다!
다음을 추가할 수 있습니다.주소 범위변경해야 할 부분에 대해. 블록 외부의 [b]
모든 항목을 변경하지 않고 시작하는 줄부터 다음 줄까지 유지하려면 [
두 표현식 사이에 쉼표가 있는 주소 범위를 선택하고(이제 변경하려는 블록만 있음) 역순으로 !
( 이제 변경하려는 블록만 있음) 다른 모든 것을 얻습니다) 명령을 사용하여 b
스크립트 끝으로 분기합니다. 따라서 각 후속 명령은 해당 범위의 행에만 영향을 미칩니다.
sed -i '/^\[b\]$/,/^\[/!b
/PATH/c\PATH=\/u01
/LOC_NAME/c\LOC_NAME=RUS'
물론 {commands;...;}
역방향 및 분기 대신 블록을 사용하여 역방향이 아닌 매칭을 수행할 수도 있지만 이는 가독성이 떨어진다고 생각합니다.
변수의 단어를 식별자로 사용하려면 다음을 수행할 수 있습니다.
ID=foo
sed -i '/^\['$ID'\]$/,/^\[/!b
/PATH/c\PATH=\/u01
/LOC_NAME/c\LOC_NAME=RUS'
답변2
awk
Perl을 사용하는 것이 더 쉬울 수도 있습니다.
$ cat input
[a]
PATH=/tmp
[b]
PATH=/tmp
OTHERPATH=/somedir
[c]
PATH=/tmp
$ gr="[b]"
$ repl=/u01
$ awk -vgr="$gr" -vrepl="$repl" '/^\[.*\]$/ { group=$0 } group == gr && /^PATH=/ { $0 = "PATH=" repl } 1' input
[a]
PATH=/tmp
[b]
PATH=/u01
OTHERPATH=/somedir
[c]
PATH=/tmp
$ gr=b
$ repl=/u01
$ gr=$gr repl=$repl perl -pe '$group = $1 if /^\[(.*)\]$/; s,^PATH=.*,PATH=$ENV{repl}, if $group eq $ENV{gr}' < input
[same output]
아이디어는 가 있는 행을 찾아 [something]
이름을 기록한 다음 해당 행에 대해 조건부 교체를 수행하는 것입니다. (awk 버전은 괄호로 그룹 이름을 사용하는 반면 Perl 버전은 그렇지 않습니다. 후자는 더 예쁘지만 awk에서는 Perl만큼 단순하지 않습니다. Perl 버전은 환경을 통해 변수를 가져오므로 다음을 수행해야 합니다 export
gr
. repl
, 또는 동일한 명령줄에서 할당).
키가 인 경우에만 교체하도록 수정했지만 PATH
여전히 PATH
동일한 제목(첫 번째 제목뿐만 아니라) [b]
아래의 모든 s를 변경하지만 두 개 이상을 가질 수 있는지 확실하지 않습니다.