Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Awk sed以某种模式在最后一个字符串之前插入一行_Awk_Sed - Fatal编程技术网

Awk sed以某种模式在最后一个字符串之前插入一行

Awk sed以某种模式在最后一个字符串之前插入一行,awk,sed,Awk,Sed,我有一个带有以下行的配置文件: *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :sdfilter - [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A sdfilter -j DROP COMMIT *nat :OUTPUT ACCEPT [0:0] :ds - [0:0] -A POSTROUTING -o dev -j MAS

我有一个带有以下行的配置文件:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:sdfilter - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A sdfilter -j DROP
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:ds - [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
我试图在eth2-j DROP中插入一行
-I FORWARD-m physdev--physdev
,该行位于
*filter
和first
COMMIT
之间,并且仅在该模式中的
COMMIT
之前。因此,生成的输出如下所示:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:sdfilter - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A sdfilter -j DROP
-I FORWARD -m physdev --physdev-in eth2 -j DROP   
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:ds - [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
我尝试了几种方法,最近的解决方案是,我可以使用sed在该模式中的每一行之前追加:

sed '/\*filter/,/COMMIT/i\FORWARD -m physdev --physdev-in eth2 -j DROP' file 

请建议我只能在过滤模式的最后一行(“提交”)之前插入的模式?

使用
awk
我可以编写

/^\*filter$/{found++}
found && /COMMIT/ {
    print "-I FORWARD -m physdev --physdev-in eth2 -j DROP";
    found=0
}
1

它是做什么的?

  • /^\*filter$/{found++}
    如果当前行是
    *filter
    ,则将
    found
    增加1

  • found&&/COMMIT/
    如果当前行具有
    COMMIT
    filter
    非零

    • 打印我们需要打印的字符串,并将
      found
      设置为零
  • 1
    这总是正确的,在这种情况下,awk执行默认任务来打印当前行


示例

$ awk '/^\*filter$/{found++} found && /COMMIT/{print "-I FORWARD -m physdev --physdev-in eth2 -j DROP"; found=0} 1' file
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:sdfilter - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A sdfilter -j DROP
-I FORWARD -m physdev --physdev-in eth2 -j DROP
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:ds - [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
*filter
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o dev -j MASQUERADE
-I FORWARD -m physdev --physdev-in eth2 -j DROP
COMMIT

使用
awk
我可以写

/^\*filter$/{found++}
found && /COMMIT/ {
    print "-I FORWARD -m physdev --physdev-in eth2 -j DROP";
    found=0
}
1

它是做什么的?

  • /^\*filter$/{found++}
    如果当前行是
    *filter
    ,则将
    found
    增加1

  • found&&/COMMIT/
    如果当前行具有
    COMMIT
    filter
    非零

    • 打印我们需要打印的字符串,并将
      found
      设置为零
  • 1
    这总是正确的,在这种情况下,awk执行默认任务来打印当前行


示例

$ awk '/^\*filter$/{found++} found && /COMMIT/{print "-I FORWARD -m physdev --physdev-in eth2 -j DROP"; found=0} 1' file
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:sdfilter - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A sdfilter -j DROP
-I FORWARD -m physdev --physdev-in eth2 -j DROP
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:ds - [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
*filter
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o dev -j MASQUERADE
-I FORWARD -m physdev --physdev-in eth2 -j DROP
COMMIT

下面是
sed
答案:

sed  -n -r '/COMMIT/{x; s/(\*filter.*)/\1\n-I FORWARD -m physdev --physdev-in eth2 -j DROP/;  p; x;p; b end }; H; b; :end n; p; b end'  config_file | sed -e '1d'
将插入的文本--替换为将在第一次“提交”之前追加的文本

解释

  • H
    将当前行追加到缓冲区
  • b
    -转到
  • -定义
  • b
    -不带任何字符,仅结束当前行处理
  • n
    -转到下一行
  • x
    -交换模式和保持缓冲区(sed中只有这两个)
  • p
    -在屏幕上打印图案缓冲区

它来了
sed
回答:

sed  -n -r '/COMMIT/{x; s/(\*filter.*)/\1\n-I FORWARD -m physdev --physdev-in eth2 -j DROP/;  p; x;p; b end }; H; b; :end n; p; b end'  config_file | sed -e '1d'
将插入的文本--替换为将在第一次“提交”之前追加的文本

解释

  • H
    将当前行追加到缓冲区
  • b
    -转到
  • -定义
  • b
    -不带任何字符,仅结束当前行处理
  • n
    -转到下一行
  • x
    -交换模式和保持缓冲区(sed中只有这两个)
  • p
    -在屏幕上打印图案缓冲区
这可能适合您(GNU-sed):

找到
*filter
COMMIT
之间的行范围,然后在包含
COMMIT
的行之前插入所需字符串,最后打印以下所有行。

这可能适用于您(GNU-sed):


找到
*filter
COMMIT
之间的行范围,然后在包含
COMMIT
的行之前插入所需字符串,最后打印以下所有行。

非常感谢您的解决方案。非常感谢您的解决方案。非常感谢您的解决方案Marek。。我唯一关心的是sed模式在文件的开头添加新行。请你改正一下好吗非常感谢你的解决方案Marek。。我唯一关心的是sed模式在文件的开头添加新行。请你改正一下好吗。