如何删除包含在特定模式后首先找到的模式的行

时间:2013-02-21 08:22:49

标签: shell unix

我正在编写一个shell脚本来删除特定组中的条目。例如:文件名是dest.xml

<domain id="1" group_name="group1">
    <node id="ABC">
    <node id="PQR">
    <node id="XYZ">
</domain>
<domain id="2" group_name="group2">
    <node id="PQR">
    <node id="XYZ">
</domain>
<domain id="3" group_name="group3">
    <node id="ABC">
    <node id="PQR">
 </domain>

我想删除上面文件中的条目(文件名是dest.xml),其中group_name =“group1”中的节点id =“PQR”(不应该从group2和group3中删除它)。我可以通过顺序读取文件然后从特定组中删除它来完成它。但是如果文件很大(> 10k行)则需要时间。

这有什么简单的方法吗?

1 个答案:

答案 0 :(得分:1)

您可以在中执行此操作:

echo '<domain id="1" group_name="group1">
    <node id="ABC">
    <node id="PQR">
    <node id="XYZ">
</domain>
<domain id="2" group_name="group2">
    <node id="PQR">
    <node id="XYZ">
</domain>
<domain id="3" group_name="group3">
    <node id="ABC">
    <node id="PQR">
 </domain>' | sed -e '/group_name="group1"/,/<\/domain>/ { /node id="PQR"/d; }'
<domain id="1" group_name="group1">
    <node id="ABC">
    <node id="XYZ">
</domain>
<domain id="2" group_name="group2">
    <node id="PQR">
    <node id="XYZ">
</domain>
<domain id="3" group_name="group3">
    <node id="ABC">
    <node id="PQR">
 </domain>

建议用法:

mv dest.xml dest.bak && sed -e '/group_name="group1"/,/<\/domain>/ { 
        /node id="PQR"/d; 
    }' dest.bak > dest.xml

Korn Shell:

请注意,环境变量不会在单引号内展开。如果您希望在脚本中嵌入此命令,则需要对命令使用双引号,然后在程序中转义双引号:

#!/bin/ksh
gp_name=group1
entry=PQR
mv dest.xml dest.bak && sed -e "/group_name=\"${gp_name}\"/,/<\/domain>/ {
    /node id=\"${entry}\"/d;
}" dest.bak > dest.xml