This command works as expected

$ awk 'BEGIN {print "\x41"}'

As does this

$ printf '\x41' | awk '{print}'

However when you rely on awk to recognize the hex characters, it fails

$ echo '\x41' | awk '{print}'

How can this be overcome?

  • 2
    I don't see the problem. Just use printf as you have or echo -e. I assume your actual use case is more complex, could you give an example of what you're actually trying to do?
    – terdon
    May 1, 2014 at 11:41
  • 1
    Ah, crap then, the -n option (see man gawk) to gawk (not awk I think) seemed promising but I couldn't get it to work.
    – terdon
    May 1, 2014 at 11:56

1 Answer 1


You'd need to do something like:

printf '%s\n' '\x41' | 
  awk 'BEGIN{for (i=0;i<0x100;i++) x[sprintf("%02x",i)]=sprintf("%c",i)}
       {print x[tolower(substr($0,3))]}'

awk can't take a hex string and convert it directly to a number, let alone a character.

That kind of thing is a lot easier done in perl. See here for a awk implementation of urldecode.

As hinted by @terdon, the GNU implementation of awk has a -n|--non-decimal-data option that allows awk to recognise hex and octal numbers on input. So you could also do:

printf '%s\n' '\x41' | gawk -n '{printf "%c\n", +("0x" substr($0,3))}'

gawk also has a strtonum() function:

printf '%s\n' '\x41' | gawk -n '{printf "%c\n", strtonum("0x" substr($0,3))}'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .