Valor ASCII entero al carácter en BASH usando printf

84

Carácter para valorar obras:

$ printf "%d\n" \'A
65
$ 

Tengo dos preguntas, la primera es la más importante:

  • ¿Cómo tomo 65 y lo convierto en A?
  • \ 'A convierte un carácter ASCII a su valor usando printf. ¿La sintaxis es específica de printf o se usa en cualquier otro lugar de BASH? (Estas cadenas pequeñas son difíciles para Google).

fuente
En Windows, use ALT + 65 para imprimir el carácter ASCII; desafortunadamente, eso no funcionará con Unix / bash;)
schnaader
2
@schnaader pero no puedes escribir eso.
ctrl-alt-delor
2
@richard: Errr ... no es fácil ni práctico, pero podría :) "Simplemente" inicie una máquina virtual con Windows o MS-DOS, envíe "echo", ALT, 6, 5, "> mysharedfolder \ file.txt" como pulsaciones de teclas y leer file.txt de la carpeta compartida de VM.
schnaader
2
@schnaader, ¿podrías usar vino para hacer eso?
emory

Respuestas:

69

Una línea

printf "\x$(printf %x 65)"

Dos lineas

set $(printf %x 65)
printf "\x$1"

Aquí hay uno si no te importa usar awk

awk 'BEGIN{printf "%c", 65}'
ampliar
fuente
3
Debería funcionar tambiénprintf "$(printf '\\x%02x' $char)"
0andriy
31

Esto funciona (con el valor en octal):

$ printf '%b' '\101'
A

incluso para (algunos: no pases de 7) secuencias:

$ printf '%b' '\'{101..107}
ABCDEFG

Una construcción general que permite valores (decimales) en cualquier rango es:

$ printf '%b' $(printf '\\%03o' {65..122})
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz

O puede usar los valores hexadecimales de los caracteres:

$ printf '%b' $(printf '\\x%x' {65..122})
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz

También puede recuperar el carácter con xxd (use valores hexadecimales):

$ echo "41" | xxd -p -r
A

Es decir, una acción es la inversa de la otra:

$ printf "%x" "'A" | xxd -p -r
A

Y también funciona con varios valores hexadecimales a la vez:

$ echo "41 42 43 44 45 46 47 48 49 4a" | xxd -p -r
ABCDEFGHIJ

o secuencias (printf se usa aquí para obtener valores hexadecimales):

$ printf '%x' {65..90} | xxd -r -p 
ABCDEFGHIJKLMNOPQRSTUVWXYZ

O incluso usa awk:

$ echo 65 | awk '{printf("%c",$1)}'
A

incluso para secuencias:

$ seq 65 90 | awk '{printf("%c",$1)}'
ABCDEFGHIJKLMNOPQRSTUVWXYZ

fuente
14

Para su segunda pregunta, parece que la sintaxis de comillas iniciales ( \'A) es específica de printf:

Si el carácter inicial es una comilla simple o una comilla doble, el valor será el valor numérico del conjunto de códigos subyacente del carácter que sigue a la comilla simple o doble.

De http://pubs.opengroup.org/onlinepubs/009695399/utilities/printf.html

David Hu
fuente
9

Una opción es ingresar directamente el carácter que le interesa usando notación hexadecimal u octal:

printf "\x41\n"
printf "\101\n"
Naaff
fuente
8

Para este tipo de conversión, uso perl:

perl -e 'printf "%c\n", 65;'
Mouviciel
fuente
2
o en perl, imprima chr (65), "\ n"; Si bien perl puede ser una buena opción si está haciendo mucho de esto, usar printf del shell para convertir su número en algo que pueda entrar en una secuencia de escape \ 0 funciona bien. Más complejo con Unicode, ya que necesita soporte en su printf.
Peter Cordes
Desafortunadamente, Perl es un idioma olvidado. Mejor es Python, que ahora está en casi todas las máquinas Linux. Además, ¡la pregunta es sobre Shell-Bash y no sobre otras plataformas!
s3n0
7

Si desea guardar el valor ASCII del carácter: (Hice esto en BASH y funcionó)

{
char="A"

testing=$( printf "%d" "'${char}" )

echo $testing}

salida: 65

MagicMercury86
fuente
Esto funcionó, gracias. Quería obtener un número entero (código ASCII) de un carácter escrito. Hice un script: {read -n 1 c; echo $ (printf "% d" "'$ {c}")}
Fedro
4

Si convierte 65a hexadecimal es 0x41:

$ echo -e "\x41" A

Cyber ​​Oliveira
fuente
si conoce el valor hexadecimal para imprimir caracteres ASCII$ printf "\x41"
katta
3

Aquí hay otra forma de convertir 65 en A (a través de octal):

help printf  # in Bash
man bash | less -Ip '^[[:blank:]]*printf'

printf "%d\n" '"A'
printf "%d\n" "'A"

printf '%b\n' "$(printf '\%03o' 65)"

Para buscar man bashpara su \'uso (aunque inútil en este caso):

man bash | less -Ip "\\\'"  # press <n> to go through the matches
chand
fuente
3

Para letras mayúsculas:

i=67
letters=({A..Z})
echo "${letters[$i-65]}"

Salida:

C
Ciro
fuente
1

esto imprime todos los caracteres "imprimibles" de su configuración básica de bash:

printf '%b\n' $(printf '\\%03o' {30..127})

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
AG6HQ
fuente