I have a list of random memory addresses saved in a text file, and I need to sed them out, decode them, and save them back to my file. However, the decoding operation I'm trying to perform is handled in a C++ program I've created some time ago. The problem I am encountering now is executing the C++ within the sed command; that is, I want to back-reference the part that needs to be decoded and use it as an argument in my C++ program. I have written the following command:

cat $1 | sed -r 's/(0[Xx])([0-9A-Za-z]{1,8})/\1`./convAddrs \2`/g';

before I had the chance to read an answer in this post saying that sed does NOT execute commands. Is it true that sed doesn't allow the execution of commands? If so, assuming the command I've written is a valid sed sequence, how would I write it in perl?


2 Answers 2

perl -pe 's|(?<=0x)[0-9a-f]{1,8}|`./convAddrs $&`|gei'
  • perl -pe: like sed: process the input one line at a time in $_, evaluate the perl [e]xpression passed to -e for each line and [p]rint the modified $_ for each.
  • s|X|Y|gei: substitute Y for X in $_ ([g]lobally, case [i]nsensitively, and treating Y as a perl [e]xpression instead of a basic string).
  • (?<=0x): look behind for 0x.
  • [0-9a-f]{1,8}: one to 8 hex digits, as many as possible
  • `./convAddrs $&`: replace by the output of that shell command line where $& is replaced by the matched part.
  • I'm getting the following error when executing your command: Having no space between pattern and following word is deprecated at -e line 1. Regexp modifiers "/a" and "/d" are mutually exclusive at -e line 1, at end of line Regexp modifiers "/a" and "/d" are mutually exclusive at -e line 1, at end of line Can't find string terminator "`" anywhere before EOF at -e line 1. Jul 31, 2013 at 17:24
  • 1
    Of course, sorry my bad, you need to change the separator as we can't use / here since it's used inside the replacement part. Corrected. Jul 31, 2013 at 17:26
  • Damn, and I though that I was pretty good at Perl one liners, +1!
    – terdon
    Aug 1, 2013 at 15:00

It may or may not be true that sed cannot execute commands. It is not true of a GNU sed:

sed -Ee 's/(0[Xx])([0-9A-Za-z]{1,8})/\1\n ./convAddrs \2\n#/g' \
-eh -e  's/\n.//gp;g;s/^/#/e' <"$1"

It's unclear to me exactly what else might be in your <$1 input, and so i take care to # comment out anything which is not command \2 in the pattern space. When you use GNU's execute flag on a s///ubstitution it passes the entire resulting pattern space to $SHELL -c as its second argument, and then subsequently replaces all of pattern-space with whatever is written to that $SHELL's stdout. So I above I print whatever your results were before first, and then after the results of passing the command-line to the shell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.