Bash sed在单个命令中交换单词

Bash sed在单个命令中交换单词,bash,sed,Bash,Sed,如何与sed交换特定单词: 考虑一行输入(在我的例子中它是一条路径): 有一条平行路径: foo/bar/PROD/foo/bar/... 我想根据原始路径交换测试和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/

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

有一条平行路径:

foo/bar/PROD/foo/bar/...
我想根据原始路径交换测试和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/...
不更改任何内容,或者更好地执行两个子条件

我正在寻找一个选项,即在第一个子条件成功时不执行第二个子条件


有什么想法或更好的方法吗?

您可以将测试操作符用于sed

sed 's#TEST#PROD#g;t;s#PROD#TEST#g' file
t标签
如果自读取最后一个输入行和最后一个t或t命令以来,s///已成功完成替换,则分支到标签;如果省略了标签,则分支到 剧本


由于没有标签,因此如手册页摘录中所述,它将分支到脚本末尾,这意味着不会执行进一步的命令。

这可能是您想要的:

$ echo 'foo/TEST/bar/PROD/foo' |
    sed 's/TEST/\n/g; s/PROD/TEST/g; s/\n/PROD/g'
foo/PROD/bar/TEST/foo
不过,并非所有SED都支持换行符的
\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来包含多行内容,它也能工作。

也许更好的例子是在输入中同时包含TEST和PROD,例如
echo'foo/TEST/bar/PROD/foo'| 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