sed在一个命令中交换单词

时间:2016-08-03 14:32:19

标签: bash sed

如何用sed交换特定单词: 考虑一行输入(在我的例子中,它是一个路径):

foo/bar/TEST/foo/bar/...

有平行路径:

foo/bar/PROD/foo/bar/...

我想根据原始路径交换TEST和PROD

我的第一次尝试是:

sed -e "s#TEST#PROD#g" -e "s#TEST#PROD/g"

但不幸的是:

echo "foo/bar/PROD/foo/bar/..." | sed -e "s#TEST#PROD#g" -e "s#PROD#TEST#g"
result: foo/bar/TEST/foo/bar/...

按预期工作,但

echo "foo/bar/TEST/foo/bar/..." | sed -e "s#TEST#PROD#g" -e "s#PROD#TEST#g"
result: foo/bar/TEST/foo/bar/...

不会改变任何东西,也不会改变两个替代品。

我正在寻找第一个成功时第二个替代品没有被执行的选项。

任何想法还是有更好的方法?

2 个答案:

答案 0 :(得分:4)

您可以将测试运算符用于sed

sed 's#TEST#PROD#g;t;s#PROD#TEST#g' file
  

t标签
                如果s ///已经读取了最后一个输入行以来的成功替换,并且从最后一个t或T命令开始,则分支到标签;如果省略label,则分支到end                 脚本。

由于没有标签,然后在手册页的摘录中提到它将分支到脚本的末尾,这意味着不再执行任何命令。

答案 1 :(得分:2)

这可能是你想要的:

$ echo 'foo/TEST/bar/PROD/foo' |
    sed 's/TEST/\n/g; s/PROD/TEST/g; s/\n/PROD/g'
foo/PROD/bar/TEST/foo

但并非所有seds都支持\n换行。这些中的任何一个都适用于任何sed:

$ echo 'foo/TEST/bar/PROD/foo' |
    sed 's/TEST/\
/g; s/PROD/TEST/g; s/\
/PROD/g'
foo/PROD/bar/TEST/foo

$ echo 'foo/TEST/bar/PROD/foo' |
    sed 's/a/aA/g; s/TEST/aB/g; s/PROD/TEST/g; s/aB/PROD/g; s/aA/a/g'
foo/PROD/bar/TEST/foo

后者具有“优势”,即使你疯狂到使用seds hold space / buffer来包含多行内容,它仍然有效。