[英]Using sed to find replace in a file but not on lines matching multiple patterns
我有一个XML
文件,可以在其中查找和替换emails
和usernames
。这很好,但是避免了一些重复的用户电子邮件等。我想跳过特定类型的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 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 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.