Joachim Weiß
Joachim Weiß

Reputation: 226

sed swap words in a single command

How do I swap specific words with sed: consider a single line of input (in my case it is a path):

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

there is parallel path:

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

I want to swap TEST and PROD depending on the original path

My first attempt was:

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

but unfortunately:

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

works as desired, but

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

does not change anything or better does both substitions.

I'm looking for an option that the second substition is not performed when the first was successful.

Any ideas or is there a even better approach?

Upvotes: 3

Views: 1910

Answers (2)

Ed Morton
Ed Morton

Reputation: 203229

This might be what you want:

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

Not all seds will support \n for a newline, though. Either of these will work in any 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

with the latter having the "advantage" that it'd work even if you were crazy enough to be using seds hold space/buffer to contain multi-line content.

Upvotes: 2

123
123

Reputation: 11216

You can use the test operator for sed

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

t label
If a s/// has done a successful substitution since the last input line was read and since the last t or T command, then branch to label; if label is omitted, branch to end of script.

As there is no label then as mentioned in the extract from the man page it will branch to the end of the script, meaning no further commands are executed.

Upvotes: 5

Related Questions