我需要用其他词替换几个词。
例如:文件
中的“apple”和“FRUIT”,仅在这 4 种情况下:
_apple_
,前后各有一个空格。[apple_
,前面有一个方括号,后面有一个空格。_apple]
,前面有一个空格,后面有一个方括号。[apple]
,前后有方括号。
我不希望在任何其他情况下发生替换。
我试过使用下面的代码:
a="apple"
b="fruit"
sed -i "s/ $a / $b /g" ./file
sed -i "s/\[$a /\[$b /g" ./file
sed -i "s/ $a\]/ $b\]/g" ./file
sed -i "s/\[$a\]/\[$b\]/g" ./file
我认为最后的选项“g”意味着它将替换所有实例,但我发现这不是一个彻底的解决方案。例如如果 file
包含这个:
apple spider apple apple spider tree apple tree
第三次出现的“apple”未被替换。同样在这里面,几个词的出现没有改变:
apple spider apple apple apple apple apple spider tree apple tree
我怀疑这是因为共享“空间”。
我怎样才能找到 $a
的所有实例并将其替换为 $b
,而不考虑任何重叠?
最佳答案
快速而肮脏的解决方案是执行两次替换。
$ echo apple apple apple apple[apple apple] | sed -e 's/\(\[\| \)apple\( \|\]\)/\1FRUIT\2/g; s/\(\[\| \)apple\( \|\]\)/\1FRUIT\2/g'
apple FRUIT FRUIT apple[FRUIT FRUIT]
这是安全的,因为在第一个命令之后,生成的文本将不会包含原始文本中不存在的任何 (\[| )apple( |\])
。
缺点是两次替换需要大约两倍的时间来运行。
如果你在 sed 的两次执行中打破它,你可以看到更清晰的步骤:
$ echo apple apple apple apple apple apple[apple apple] | sed -e 's/\(\[\| \)apple\( \|\]\)/\1FRUIT\2/g'
apple FRUIT apple FRUIT apple apple[FRUIT apple]
$ echo apple FRUIT apple FRUIT apple apple[FRUIT apple] | sed -e 's/\(\[\| \)apple\( \|\]\)/\1FRUIT\2/g'
apple FRUIT FRUIT FRUIT FRUIT apple[FRUIT FRUIT]
关于regex - 当区域重叠时,Sed 不会替换文件中的所有实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8752268/