我想添加两行
allow = alaw
allow = g729
在字符串之前
nat = no
在文件sip.conf
(或任何基于文本的文件)中。如果allow = alaw
和allow = g729
之前已经存在,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
allow = g729
nat = no
progressinband = yes
预期产出
[general]
disallow = all
allow = ulaw
nat = no
[providertrunk0]
disallow = all
allow = ulaw
;allow = alaw
nat = no
secret =
allow = alaw
allow = g729
nat = no
progressinband = yes
allow = ulaw
allow = alaw
allow = g729
nat = no
progressinband = yes
disallow = all
allow = ulaw
allow = alaw
allow = g729
nat = no
progressinband = yes
我的尝试
cat addCodec.awk
BEGIN {
RS=""; ORS="\n\n"; FS=OFS="\n"
skip["[general]"]
skip["[providertrunk0]"]
addCodec = "allow = alaw\nallow = g729"
tgt = "nat = no"
}
!($1 in skip) {
for (i=1; i<NF; i++) {
if ( ($i != addCodec) && ($(i+1) == tgt) ) {
$i = $i OFS addCodec
}
}
}
{ print }
awk -f addCodec.awk sip.conf
如果这两行都不存在,此脚本将起作用,它将添加它们。如果存在单行,那么我就会陷入困境,如果我需要使用条件怎么办?
答案1
我不是awk
(but python
) 方面的专家,但$i
给出了单行,然后将它与有两行的字符串进行比较"allow = alaw\nallow = g729"
- 这是问题。您应该单独检查每一行。
$(i-1)
我创建了分别检查和$(i-2)
比较"allow = alaw"
(第一)和(第二)的代码"allow = g729"
。这样我就分为三种情况
FIRST - exist, SECOND - missed
FIRST - missed, SECOND - missed
FIRST - missed, SECOND - exist
并为$i
or添加不同的值$(i-1)
BEGIN {
RS=""; ORS="\n\n"; FS=OFS="\n"
skip["[general]"]
skip["[providertrunk0]"]
addCodec1 = "allow = alaw"
addCodec2 = "allow = g729"
tgt = "nat = no"
}
!($1 in skip) {
for (i=1; i<NF; i++) {
if ($(i) == tgt) {
# FIRST - exist, SECOND - missed
if ( ($(i-1) == addCodec1) ) {
$i = addCodec2 OFS $i
}
# FIRST - missed, SECOND - missed
else if ( ($(i-1) != addCodec1) && ($(i-1) != addCodec2) ) {
$i = addCodec1 OFS addCodec2 OFS $i
}
# FIRST - missed, SECOND - exist
else if ( ($(i-2) != addCodec1) && ($(i-1) == addCodec2) ) {
$(i-1) = addCodec1 OFS $(i-1)
}
}
}
}
{ print }
顺便提一句:为了使它更加不活泼(也更简单),我会用不同的参数运行它两次。
第一个仅放在"allow = g729"
之前"nat = no"
,第二个仅放在"allow = alaw"
之前"allow = g729"
。
这样我就可以再次运行它以放置"third line"
before"allow = alaw"
并再次运行它以放置"fourth line"
before"third line"
等。
答案2
修改您现有的尝试。查看各种可能场景的复杂性被封装在用户定义的函数 fx() 中。根据找到的 tgt 线的索引,绘制了各种可能的情况。
$ cat addCodec.txt
BEGIN {
RS=""; ORS="\n\n"; FS=OFS="\n"
skip["[general]"]
skip["[providertrunk0]"]
e1 = "allow = alaw"
e2 = "allow = g729"
a[e2] = a[e1] = 1
addCodec = e1 OFS e2
tgt = "nat = no"
}
!($1 in skip) {
for (i=1; i<=NF; i++) {
if ($i "" == tgt) {
fx(i)
break
}
}
}
{ print }
function fx(i, cond) {
cond = (i>2 ? (a[$(i-2)]+0) : 0) "" (i>1 ? (a[$(i-1)]+0) : 0)
if ( cond "" == "11" ) { $(i-2) = e1; $(i-1) = e2 }
else if ( cond "" == "01" ) { $(i-1) = addCodec }
else if ( cond ~ /0$/ ) { $(i) = addCodec OFS $(i) }
}
$ awk -f addCodec.txt file