Bash – Using a Command Inside a Sed Substitution

bashcommand-substitutionsed

I am trying to use sed to replace a sequence of the same characters with the amount of characters in that sequence, but somehow something goes wrong.

I am trying the following:

echo aaabbdd | sed -e 's/a*/'"`wc -m &`/"

But this returns 0bbdd while I would like it to return 3bbdd.

I don't really know what exactly goes wrong sed seems to know what to replace and tries to execute the wc command, but somehow wc counts something empty? I am out of ideas of how to solve this problem, can somebody help me?

Thank you!

Best Answer

What you are trying to achieve is possible indeed, but only with GNU sed, using the e command. So if you don't mind possible portability issues, you can give it a try.

E.g. your example will look something like this:

>echo aaabbdd | sed -e 's/a*/echo `echo -n & | wc -m`/;e'
3bbdd

if you remove the ;e, you will see an intermediate command (which helps understand why there are two echo'es)

echo `echo -n aaa | wc -m`bbdd

If you want to replace multiple matches, this could be more tricky, but still can be done by chaining substitutions:

>echo aabbaadd | sed -re 's/a+/`echo -n &|wc -m`/g;s/.*/echo &/;e'
2bb2dd

And certainly there are better tools for your task, such as awk, which features a built-in length() function.

References:

P.S.

Also take a note that if your input data contains quotes, you will have to escape them carefully, or temporarily replace them (i.e. with sed y/// command) for this to work.

Related Question