줄을 추가하고 싶어요
allow = alaw
문자열 앞에
nat = no
파일 sip.conf
(또는 텍스트 기반 파일)에서. allow = alaw
이전에 이미 존재 했다면 nat = no
추가하면 안 됩니다. 그리고 이 줄은 파일 [general]
바로 뒤와 두 섹션에 추가되어서는 안 됩니다 [providertrunk0]
.
파일 내용의 예:
[general]
disallow = all
allow = ulaw
nat = no
[providertrunk0]
disallow = all
allow = ulaw
;allow = alaw
nat = no
secret =
nat = no
progressinband = yes
allow = ulaw
allow = alaw
nat = no
progressinband = yes
disallow = all
allow = ulaw
nat = no
progressinband = yes
변경 후에는
[general]
disallow = all
allow = ulaw
nat = no
[providertrunk0]
disallow = all
allow = ulaw
;allow = alaw
nat = no
secret =
allow = alaw
nat = no
progressinband = yes
allow = ulaw
allow = alaw
nat = no
progressinband = yes
disallow = all
allow = ulaw
allow = alaw
nat = no
progressinband = yes
내 시도
[general]
AND 부분의 전체 프로세스를 제외 하고 다음을 [providertrunk0]
사용하여 전체 파일에 적용해 보았습니다 .'/general/,/providertrunk0/{next}'
awk -v add="allow = alaw" '/general/,/providertrunk0/{next} /^nat = no$/&&lastLine!=add{print add}{lastLine=$0}1' sip.conf '
그러나 올바른 출력을 제공하지 않습니다.
답변1
$ cat tst.awk
BEGIN {
RS=""; ORS="\n\n"; FS=OFS="\n"
skip["[general]"]
skip["[providertrunk0]"]
add = "allow = alaw"
tgt = "nat = no"
}
!($1 in skip) {
for (i=1; i<NF; i++) {
if ( ($i != add) && ($(i+1) == tgt) ) {
$i = $i OFS add
}
}
}
{ print }
.
$ awk -f tst.awk file
[general]
disallow = all
allow = ulaw
nat = no
[providertrunk0]
disallow = all
allow = ulaw
;allow = alaw
nat = no
secret =
allow = alaw
nat = no
progressinband = yes
allow = ulaw
allow = alaw
nat = no
progressinband = yes
disallow = all
allow = ulaw
allow = alaw
nat = no
progressinband = yes
RS를 null로 설정하면 awk가 단락 모드로 설정됩니다 RS = ""
(https://www.gnu.org/software/gawk/manual/gawk.html#Multiple-Line) 따라서 입력은 빈 줄로 구분된 여러 줄의 레코드로 분할됩니다. ORS="\n\n"을 설정하면 출력 시 레코드 사이에 빈 줄이 있게 됩니다. FS 및 OFS를 "\n"으로 설정하면 레코드가 필드로 분할된다는 의미입니다. 따라서 특정 필드(행)를 질문에 언급된 값과 비교하면 나머지 코드는 간단합니다. skip[]
첫 번째 필드(첫 번째 행) 문자열을 저장하는 배열에 대해 작성한 이름입니다. 해당 배열에서 추가 처리를 위해 해당 문자열을 무시하고 각 레코드에 대해 첫 번째 레코드가 필드/행에 있는지 테스트하고 싶습니다. 배열인 경우 처리를 건너뜁니다.