我找到了XML
个文件,正在替换emails
和usernames
。
这一切都很好,但要避免一些重复的用户电子邮件等。我想跳过特定类型的XML元素。
如果我想跳过一个特定时间,我就可以这样做。
/ApplicationUser/!s/"user.name"/"user.name@abc.com"/g
但如果我在一个sed命令上尝试多次
,那就不行了/(OtherElement|ApplicationUser)/!s/"user.name"/"user.name@abc.com"/g
OR
/\(OtherElement\|ApplicationUser\)/!s/"user.name"/"user.name@abc.com"/g
OR
/\(OtherElement|ApplicationUser\)/!s/"user.name"/"user.name@abc.com"/g
如果相关,我正在加载文件中的命令。我假设它在开始时与我的模式有关,试图匹配1个或多个单词,但不确定。
答案 0 :(得分:1)
因此,正则表达式语法取决于您正在使用的sed版本。
首先,根据POSIX规范,basic regular expressions (BRE) do not support alternation。但是,工具不一定遵循规范,特别是不同版本的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"
答案 1 :(得分:0)
这可能适合你(GNU sed):
sed '/OtherElement\|ApplicationUser/b;s/"user.name"/"user.name@abc.com"/g file
在遇到你不想处理的一行时,爆发,获取下一行并重复。
答案 2 :(得分:0)
只需使用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。