user1419416
user1419416

Reputation: 13

Pipes inside of sed

Is there a way to send the back references of the SED s/// command to pipes? In order to get an entry from the text, change it, and then write it back. I found that a substitution inside of SED works:

$ echo 'Test ....' | sed 's/Test/'$( echo "<\0>" )'/' 
<Test> ....

But the first pipe does not:

$ echo 'Test ....' | sed 's/Test/'$( echo "<\0>" | tr 's' 'x' )'/' 
<Test> ....

What is the reason? Additionally, I can't understand why this works at all. I thought that $() substitution should be processed before sed (all the more as I broke the quotes).

And how can I insert one s/// command into another using sed? I use bash.

Upvotes: 1

Views: 406

Answers (2)

Thor
Thor

Reputation: 47099

You can achieve the effect you're after with GNU sed and the e flag:

echo 'Test ....' | sed 's/Test.*/echo "<\0>" | tr s x/e'

Output:

<Text ....>

Upvotes: 2

chepner
chepner

Reputation: 530970

The tr command is operating on the text "<\0>", not on "<Test>". The back reference isn't expanded in sed until after the pipeline completes. Your second example is equivalent to

foo=$( echo "<\0>" | tr 's' 'x' )
echo 'Test ....' | sed 's/Test/'$foo'/'

It's a little easier to see here that tr has no way of seeing "Test" in its input.

Upvotes: 4

Related Questions