3

I would like to print directly with sed a HEX value translation by isolating the HEX values in capture groups. This works:

echo bbb3Accc | sed -n 's/3A/\x3A/p'
bbb:ccc

...but this doesn't work:

echo bbb3Accc | sed 's/\(3A\)/\x\1/'
bbbx3Accc

...or an actual capture group REGEX matching based on URL encoded strings:

echo bbb%3Accc | sed 's/%\([A-Za-z0-9]\)/\x\1/'
bbbx3Accc

Apparently sed no longer interprets and translates the HEX value if it is constructed from a REGEX capture group, together with the \x escape.

But I am wondering if there's a workaround that I am not aware of, to make this work only with sed. Note that I am aware that I can do a bash command substitution and wrap the sed syntax in a echo -e but I would like to avoid that.

one-liner
  • 791
  • 1
  • 9
  • 19
  • Check https://stackoverflow.com/questions/5777170/substitution-with-sed-bash-function – Wiktor Stribiżew Apr 13 '18 at 13:31
  • 1
    `\x\1` would result in `\x` and `\1` (as `\x` expects two hex digits after it but ``\``appearing cuts it off)... `\x` has no special meaning, so just prints `x`... I don't think there is any way to do this in sed... you can use perl... not sure about awk, but there might be a way with match/substr – Sundeep Apr 13 '18 at 13:34
  • It's about the same kind of issue with (GNU) awk. This works: `awk 'BEGIN {printf "%c\n",0x3A}'` (prints `:` correctly) but this fails miserably `echo 0x3A | awk '{printf "%c\n",$1}'` – one-liner Apr 13 '18 at 13:49
  • @linux_newbie to convert a non-decimal string to a number in awk you use `strtonum()`, for example this: `echo 0x3A | gawk '{printf "%c\n",strtonum($1)}'` outputs `:`. – Ed Morton Apr 15 '18 at 15:40

2 Answers2

1

Your question isn't clear but maybe this is what you're trying to do using GNU awk for multi-char RS, RT, and strtonum():

$ echo 'bbb%3Accc%21ddd' |
gawk -v RS='%[[:xdigit:]]{2}' 'sub(/%/,"0x",RT){RT=sprintf("%c",strtonum(RT))} {ORS=RT} 1'
bbb:ccc!ddd
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • 1
    Thanks for the reply, this does the job for the example I posted. But the reason I wanted to do it with sed is to perform multiple substitutions on a given line and print everything, something line `bbb%3Accc%21ddd` that would produce `bbb:ccc!ddd` etc. Up until now, the simplest way to do it is to do a sed command substitution in a `echo -e` – one-liner Apr 16 '18 at 08:28
  • In shell programming often "simple" really means "brief and buggy" so YMMV with an echo+sed combo vs doing it robustly in awk. Just really **think** about your requirements and what the script you have in mind is doing. I updated my answer based on your updated requirements and example. – Ed Morton Apr 16 '18 at 15:04
  • 1
    Thank you, I really didn't think of using RS + RT. – one-liner Apr 16 '18 at 23:24
0

As mentioned in the comments, \xAB is interpreted by sed's parser, rather than as an expression, so \x won't work in the way you were trying.

sed is pretty primitive and your example is beyond what it is intended for, so you'd be better off using something more general purpose. For example, in Perl:

$ echo bbb3Accc | perl -ple 's/([0-9A-F]{2})/chr(hex($1))/ge'
bbb:ccc
Jon
  • 3,573
  • 2
  • 17
  • 24
  • I see. It does work but only when I actually write in the HEX code (per my example), as opposed to placing it via REGEX capture group. Surprisingly (or maybe not), `awk` does the same (check my reply to the first comment). – one-liner Apr 13 '18 at 14:59