使用SED时如何保留部分字符串?

时间:2013-11-27 19:47:39

标签: vim replace

我在这样的文件中有多行

APPLE JUICE
APPLE JAM
APPLE JELLY

我想用“ORANGE”替换“APPLE”并在字符串的末尾添加“SHOP”。输出将是

ORANGE JUICE SHOP
ORANGE JAM SHOP
ORANGE JELLY SHOP

如何在sed或vim中执行此操作?

EDIT1: 我发现了一个适用于sed的解决方案

#replace APPLE with ORANGE 
sed -i s/APPLE/ORANGE/g foo.txt
#in a line containing ORANGE replace newline with SHOP
sed -i '/ORANGE/s/$/ SHOP/g'

现在的问题是我无法让第二个命令在vim中工作。所以现在这是个问题。

4 个答案:

答案 0 :(得分:2)

不,@ Kent的回答elide行不包含APPLE并将SHOP附加到文件中的所有行。您需要使用RE子表达式:

echo "APPLE JUICE\
CHERRY JAM\
APPLE JELLY" | sed 's/^APPLE \(.*\)$/ORANGE \1 SHOP/'
ORANGE JUICE SHOP
CHERRY JAM
ORANGE JELLY SHOP

答案 1 :(得分:2)

在vim中,在命令模式下尝试这个

:%s​​ / APPLE \(。* \)/ ORANGE \ 1 SHOP / g

答案 2 :(得分:0)

你去:

kent$  echo "APPLE JUICE
APPLE JAM
APPLE JELLY"|sed 's/\bAPPLE\b/ORANGE/;s/$/ SHOP/'
ORANGE JUICE SHOP
ORANGE JAM SHOP
ORANGE JELLY SHOP

我添加了字边界,因此PINEAPPLE之类的内容不会被PINEORANGE替换

在vim中,有同样的想法:

%s/\<APPLE\>/ORANGE/|%s/$/ SHOP/

修改

当我发布答案时,没有要求仅在存在ORANGE匹配时附加SHOP。 OP在我的回答后更新了问题。

无论如何,我添加了另一个vim cmd:

%s/\<APPLE\>/ORANGE/g|%s/.*\<ORANGE\>.*/& SHOP/

答案 3 :(得分:0)

@dyomas是对的,@ Kent的答案不加选择地将SHOP附加到所有行。

以下是不使用子表达式的解决方案;相反,它使用t命令来测试替换,然后只追加SHOP

sed 's/\bAPPLE\b/ORANGE/; t append; b; :append s/$/ SHOP/'

因为t命令在替换的情况下跳转(但我们需要相反),我们必须“跳过”b命令,否则将中止行处理。