繁体   English   中英

使用sed在文件中查找替换,但不在与多个模式匹配的行上查找

[英]Using sed to find replace in a file but not on lines matching multiple patterns

我有一个XML文件,可以在其中查找和替换emailsusernames 。这很好,但是避免了一些重复的用户电子邮件等。我想跳过特定类型的XML元素。

如果我想跳过一个特定的时间,我可以这样做

/ApplicationUser/!s/"user.name"/"user.name@abc.com"/g

但是如果我在一个sed命令上尝试多个命令则不会

/(OtherElement|ApplicationUser)/!s/"user.name"/"user.name@abc.com"/g

要么

/\(OtherElement\|ApplicationUser\)/!s/"user.name"/"user.name@abc.com"/g

要么

/\(OtherElement|ApplicationUser\)/!s/"user.name"/"user.name@abc.com"/g

如果相关,我正在从文件中加载命令。 我假设它一开始就与我的模式有关,试图匹配1个或多个单词,但不确定。

因此,正则表达式语法取决于您所使用的sed版本。

首先,根据POSIX规范, 基本正则表达式(BRE)不支持alteration 但是,工具不一定符合规范,特别是sed的不同版本具有不同的行为。

下面的示例都在处理此文件:

$ cat sed-re-test.txt
OtherElement "user.name"
OnlyReplaceMe "user.name"
ApplicationUser "user.name"

GNU sed

GNU sed BRE变体支持轮换,但是| 元字符(以及() )必须使用\\进行转义。 如果使用-E标志启用扩展正则表达式(ERE),则不得转义元字符。

$ sed --version
sed (GNU sed) 4.4
<...SNIP...>

GNU sed BRE变体(带有转义的元字符): WORKS

$ cat sed-re-test.txt  | sed '/\(OtherElement\|ApplicationUser\)/!s/"user.name"/"user.name@abc.com"/g'
OtherElement "user.name"
OnlyReplaceMe "user.name@abc.com"
ApplicationUser "user.name"

GNU sed ERE(具有转义的元字符): WORKS

$ cat sed-re-test.txt  | sed -E '/(OtherElement|ApplicationUser)/!s/"user.name"/"user.name@abc.com"/g'
OtherElement "user.name"
OnlyReplaceMe "user.name@abc.com"
ApplicationUser "user.name"

BSD / MacOS sed

BSD sed在BRE模式下不支持交替。 您必须使用-E启用替代支持。

没有--version标志,因此标识操作系统必须执行以下操作:

$ uname -s
OpenBSD

BSD sed BRE(带有转义和未转义的元字符): 不起作用

$ cat sed-re-test.txt  | sed '/\(OtherElement\|ApplicationUser\)/! s/"user.name"/"user.name@abc.com"/'
OtherElement "user.name@abc.com"
OnlyReplaceMe "user.name@abc.com"
ApplicationUser "user.name@abc.com"

$ cat sed-re-test.txt  | sed '/(OtherElement|ApplicationUser)/! s/"user.name"/"user.name@abc.com"/'
OtherElement "user.name@abc.com"
OnlyReplaceMe "user.name@abc.com"
ApplicationUser "user.name@abc.com"

BSD sed ERE(带有转义的元字符): WORKS

$ cat sed-re-test.txt  | sed -E '/(OtherElement|ApplicationUser)/! s/"user.name"/"user.name@abc.com"/'
OtherElement "user.name"
OnlyReplaceMe "user.name@abc.com"
ApplicationUser "user.name"

这可能对您有用(GNU sed):

sed '/OtherElement\|ApplicationUser/b;s/"user.name"/"user.name@abc.com"/g file

遇到您不想处理的行时,请中断并获取下一条并重复。

只需使用awk,避免复杂的,向后的逻辑( if X do NOT do Y but do Y for everything else而简单逻辑, if NOT X do Y ),以及避免使用sed的版本特定的构造。

awk '!/OtherElement|ApplicationUser/{ gsub(/"user.name"/,"\"user.name@abc.com\"") } 1' file

这是清晰,简单,可扩展的,并且可以在任何UNIX机器上的任何shell中的任何awk中使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM