我有一个包含行的配置文件:
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
* at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* @param o element whose presence in this list is to be tested
* @return <tt>true</tt> if this list contains the specified element
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
我试图在*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
和第一个-I FORWARD -m physdev --physdev-in eth2 -j DROP
之间插入一行*filter
,并且只在该模式中的COMMIT
之前插入。所得到的输出如下所示:< / p>
COMMIT
我尝试了几种方法,最接近的解决方案是我可以使用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
-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
请建议一种模式,我只能在该过滤模式中的最后一行(“COMMIT”)行之前插入?
答案 0 :(得分:0)
使用awk
我可以写,
/^\*filter$/{found++}
found && /COMMIT/ {
print "-I FORWARD -m physdev --physdev-in eth2 -j DROP";
found=0
}
1
<小时/> 是什么?
/^\*filter$/{found++}
如果当前行为*filter
,则递增found
一个。
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
答案 1 :(得分:0)
来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'
将 - 插入的文字替换为首先在'COMMIT'之前附加的文字,plaese。
<强>解释强>
H
将当前行追加到缓冲区b <label>
- 转到: <label>
- 定义b
- 没有简单地结束当前行处理n
- 转到下一行x
- 交换模式和保持缓冲区(sed
中只有两个)p
- 屏幕上的打印模式缓冲区答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -e '/^\*filter/,/^COMMIT/{/^COMMIT/{i-I FORWARD -m physdev --physdev-in eth2 -j DROP' -e ':a;n;ba}}' file
找出*filter
和COMMIT
之间的行范围,然后在包含COMMIT
的行之前插入所需的字符串,最后打印所有后续行。