Você precisa fazer algo como:
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 não aceita uma string hexadecimal e a converte diretamente em um número, sem falar em um caractere.
Esse tipo de coisa é muito mais fácil em perl . Consulte aqui para obter uma awk de implementação de urldecode .
Como sugerido por @terdon , a implementação do GNU de awk tem uma opção -n|--non-decimal-data que permite que awk reconheça números hexadecimais e octal na entrada. Então você também pode fazer:
printf '%s\n' '\x41' | gawk -n '{printf "%c\n", +("0x" substr($0,3))}'
gawk também tem uma função strtonum() :
printf '%s\n' '\x41' | gawk -n '{printf "%c\n", strtonum("0x" substr($0,3))}'