sed删除所有匹配事件的一部分

时间:2015-01-07 07:11:49

标签: linux bash unix awk sed

我有一个文件“names.xml”,如下所示:

    NAME="James"
    NAME="Jack_DONE"
    NAME="John_DONE"
    NAME="Jimmy"

我想使用单个SED行命令查找所有出现的'NAME =“J'在'”中有'_DONE',我想从找到的所有匹配项中仅删除'_DONE'。

所以结果应该是这样的:

    NAME="James"
    NAME="Jack"
    NAME="John"
    NAME="Jimmy"

这是我正在使用的命令:

sed 's/^[^#]\(.*\)NAME="J\(.*\)_DONE"/\1"NAME=J\2"/' names.xml

我相信我能以更有效的方式做到这一点! 非常感谢您的时间和帮助。

4 个答案:

答案 0 :(得分:5)

使用GNU sed:仅在包含NAME="J的行中搜索_DONE并替换为空。

sed '/NAME="J/{s/_DONE//}' names.xml

输出:

    NAME="James"
    NAME="Jack"
    NAME="John"
    NAME="Jimmy"

答案 1 :(得分:3)

您可以使用:

sed -i.bak -r '/^#/!s/(NAME="J[^"]*)_DONE"/\1"/' file
NAME="James"
NAME="Jack"
NAME="John"
NAME="Jimmy"

答案 2 :(得分:2)

只需稍微调整即可修正引号和缩进的位置:

sed 's/^\([^#].*\)NAME="J\(.*\)_DONE"/\1NAME="J\2"/' names.xml

答案 3 :(得分:0)

以下是awk版本:

awk '/NAME="J/ {sub(/_DONE/,"")}1' names.xml
    NAME="James"
    NAME="Jack"
    NAME="John"
    NAME="Jimmy"

将其写回文件:

awk '/NAME="J/ {sub(/_DONE/,"")}1' names.xml > tmp && mv tmp names.xml

或者如果您有gnu awk >= 4.1

awk -i '/NAME="J/ {sub(/_DONE/,"")}1' names.xml