使用 awk 在文件中的字符串前添加两行

使用 awk 在文件中的字符串前添加两行

我想添加两行

allow = alaw
allow = g729

在字符串之前

nat = no

在文件sip.conf(或任何基于文本的文件)中。如果allow = alawallow = 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

并为$ior添加不同的值$(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

相关内容