awk를 사용하여 파일의 문자열 앞에 줄을 추가하세요.

awk를 사용하여 파일의 문자열 앞에 줄을 추가하세요.

줄을 추가하고 싶어요

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[]첫 번째 필드(첫 번째 행) 문자열을 저장하는 배열에 대해 작성한 이름입니다. 해당 배열에서 추가 처리를 위해 해당 문자열을 무시하고 각 레코드에 대해 첫 번째 레코드가 필드/행에 있는지 테스트하고 싶습니다. 배열인 경우 처리를 건너뜁니다.

관련 정보