bash 脚本中 sunOS 的 sed - 替换模式:没有变化

sunOS's sed in bash script - replace pattern: nothing changes

答案:

mlv and sorontar所述,我的 SED 版本是 BRE,不支持 | (管道)。所以在我的情况下可以使用类似的东西:

sed "s/\( [namevlu]*=\"\)BASE\.$str1/BASE\.$str2/g"

匹配 name="value=" 但不匹配 other="values="。正则表达式([namevlu])只包含我需要的字符。好的,它不像可以那样保存,但我不希望存在 valuenm=" 之类的东西。如果有人需要 exactly 指定正则表达式,它需要制作两个(或更多)seds。

原始问题:

我需要用另一个字符串替换一个字符串,但我肯定需要检查特定的上下文。

例如:

blah val1="BASE.OLD_TEXT_OR_SO" blabla
blah val2="BASE.OLD_SOMETHING" ...

我想改成

blah val1="BASE.NEW_TEXT_OR_SO" blabla
blah val2="BASE.NEW_SOMETHING" ...

这个脚本没有任何改变:

#!/bin/bash

...

str1="OLD_"
str2="NEW_"

sed "s/\(name=\"|value=\"\)BASE\.$str1/BASE\.$str2/g" input.file > output.file

但后来类似的 sed 工作正常:

sed "s/\(<Tag>\)[A-Z0-9\-\._|]*\(<\/Tag>\)/$otherStr/g" input.file > output.file

输出文件还有 BASE.OLD_ :/

同样,当我在控制台上尝试时,我得到了相同的 (none) 结果。我认为 "looking for" 模式有问题,但我不知道是什么。

$ str0='blah name="BASE.OLD_TEXT_OR_SO" blabla 
> blah value="BASE.OLD_SOMETHING" ...
> blah other="BASE.OLD_SOMETHING" ...
> blah values="BASE.OLD_SOMETHING" ...'
$ echo $str0  | sed "s/\(val1=\"|val2=\"\)BASE\.$str1/BASE\.$str2/g"

正则表达式在 online tester 上进行了测试,它工作正常。

(name="|value=")BASE\.OLD_
BASE\.NEW_

系统:
SunOS 5.11
GNU bash 4.1.11(1)-发布
Sed 4.2.1

提前致谢。

我不确定 SunOS sed 是否包含 |。那将添加 -r 我认为 SunOS sed 不支持。

但在这种情况下,您应该能够做到:

sed "s/\(val[12]=\"\)BASE.$str1/BASE.$str2/"

如果你不能用val[12],那我觉得sed也做不到。但在 perl 中并不难:

perl -pe "if (/val1=BASE.$str1/ || /val2=BASE.$str1/) {s/BASE.$str1/BASE.$str2/;}"

a basic sed only BRE are supported, (POSIX BRE)和交替(|)中不存在。 您的正则表达式必须写成:

sed "s/\(val[12]=\"BASE\.\)${str1}/${str2}/g" input.file

如果你使用的sed版本支持(extended) ERE (which accepts the |)那么你可以使用:

sed -E "s/(val(1|2)=\"BASE\.)${str1}/${str2}/g" input.file

mlv and sorontar所述,我的 SED 版本是 BRE,不支持 | (管道)。所以在我的情况下可以使用类似的东西:

sed "s/\( [namevlu]*=\"\)BASE\.$str1/BASE\.$str2/g"

匹配 name="value=" 但不匹配 other="values="。正则表达式([namevlu])只包含我需要的字符。好的,它不像可以那样保存,但我不希望存在 valuenm=" 之类的东西。如果有人需要 exactly 指定正则表达式,它需要制作两个(或更多)seds。