行を追加したい
allow = alaw
文字列の前に
nat = no
ファイルsip.conf
(またはテキストベースのファイル)から。allow = alaw
以前にすでに存在していた場合は、nat = no
追加しないでください。そして、この行はファイルの[general]
直後と2つのセクションに追加しないでください[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[]
最初のフィールド(最初の行)文字列を格納する配列に対して作成した名前。その配列でさらに処理するためにその文字列を無視し、各レコードに対して最初のレコードがフィールド/行にあるかどうかをテストしたいと思います。配列の場合は処理をスキップします。