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
和firstCOMMIT
之间,并且仅在该模式中的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
增加1found
如果当前行具有found&&/COMMIT/
且COMMIT
非零filter
- 打印我们需要打印的字符串,并将
设置为零found
- 打印我们需要打印的字符串,并将
这总是正确的,在这种情况下,awk执行默认任务来打印当前行1
示例
$ 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
增加1found
如果当前行具有found&&/COMMIT/
且COMMIT
非零filter
- 打印我们需要打印的字符串,并将
设置为零found
- 打印我们需要打印的字符串,并将
这总是正确的,在这种情况下,awk执行默认任务来打印当前行1
示例
$ 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
-交换模式和保持缓冲区(sed中只有这两个)x
-在屏幕上打印图案缓冲区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
-交换模式和保持缓冲区(sed中只有这两个)x
-在屏幕上打印图案缓冲区p
*filter
和COMMIT
之间的行范围,然后在包含COMMIT
的行之前插入所需字符串,最后打印以下所有行。这可能适用于您(GNU-sed):
找到
*filter
和COMMIT
之间的行范围,然后在包含COMMIT
的行之前插入所需字符串,最后打印以下所有行。非常感谢您的解决方案。非常感谢您的解决方案。非常感谢您的解决方案Marek。。我唯一关心的是sed模式在文件的开头添加新行。请你改正一下好吗非常感谢你的解决方案Marek。。我唯一关心的是sed模式在文件的开头添加新行。请你改正一下好吗。