perlsed

sed or perl replacing sub string only, with the result of other command


How, by one-liner sed or perl, to replace a sub string only, with the result of other command execution, in the middle of full line string e.g:

$ cat f
iiiiiii
OOO=dd=XXX
uuuuuuu

it's clear in string line with distinct substring patterned =dd= would be captured to be executed by a command, say, type -p

e.g. sed is:

$ sed -E 's/^O+=([a-z]\w+)=X+$/type -p \1/e' f

but the result is only the command execution's one, with no complete two adjacent strings, i.e. fails to get the correct solution

OOO=/usr/bin/dd=XXX

So help out how to accomplish up to the correct solution by sed or perl (or both if being so generous)


Solution

  • You need to use more capture groups and tweaking of replacement string to get it right like this:

    sed -E 's/^(O+=)([a-z]\w*)(=X+)$/echo "\1$(type -p \2)\3"/e' f
    
    iiiiiii
    OOO=/usr/bin/dd=XXX
    uuuuuuu
    

    We have 3 capture groups:

    • ^: Start
    • (O+=): Match 1+ of O followed by a =. Capture this in 1st group
    • ([a-z]\w*): Match [a-z] followed by 0 or more word characters. Capture this in 2nd group
    • (=X+): Match = followed by 1+ of X. Capture this in 3rd group
    • $: End
    • echo "\1$(type -p \2)\3 is used to put \1 followed by type -p \2 followed by \3 in the substitution.

    Online Demo

    As commented below by @TLP, this command can be made more generic by using:

    sed -E 's/^([^=]+=)(\w+)(=.*)$/echo "\1$(type -p \2)\3"/e' f