Valore ASCII intero in caratteri in BASH utilizzando printf


85

Il carattere da valorizzare funziona:

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

Ho due domande, la prima è la più importante:

  • Come prendo 65 e lo trasformo in A?
  • \ 'A converte un carattere ASCII nel suo valore usando printf. La sintassi è specifica per printf o è usata da qualche altra parte in BASH? (Stringhe così piccole sono difficili per Google.)
bash  ascii  printf 

In Windows, usa ALT + 65 per stampare il carattere ASCII - sfortunatamente non funzionerà usando Unix / bash;)
schnaader

2
@schnaader ma non puoi scrivere questo.
ctrl-alt-delor

2
@richard: Errr .. non è facile né pratico, ma potresti :) "Basta" avviare una VM con Windows o MS-DOS, inviare "echo", ALT, 6, 5, "> mysharedfolder \ file.txt" come preme i tasti e legge file.txt dalla cartella condivisa della VM.
schnaader

2
@schnaader potresti usare il vino per farlo?
emory

Risposte:


70

Una linea

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

Due righe

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

Eccone uno se non ti dispiace usare awk

awk 'BEGIN{printf "%c", 65}'

3
Dovrebbe funzionare ancheprintf "$(printf '\\x%02x' $char)"
0andriy

31

Funziona (con il valore in ottale):

$ printf '%b' '\101'
A

anche per (alcune: non andare oltre 7) sequenze:

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

Un costrutto generale che consente valori (decimali) in qualsiasi intervallo è:

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

Oppure puoi usare i valori esadecimali dei caratteri:

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

Puoi anche recuperare il carattere con xxd (usa valori esadecimali):

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

Cioè, un'azione è il contrario dell'altra:

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

E funziona anche con più valori esadecimali contemporaneamente:

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

o sequenze (printf è usato qui per ottenere valori esadecimali):

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

Oppure usa awk:

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

anche per le sequenze:

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


9

Un'opzione è inserire direttamente il carattere che ti interessa utilizzando la notazione esadecimale o ottale:

printf "\x41\n"
printf "\101\n"

8

Per questo tipo di conversione, utilizzo perl:

perl -e 'printf "%c\n", 65;'

2
o in perl, print chr (65), "\ n"; Mentre perl potrebbe essere una buona scelta se stai facendo molto di questo, usare printf della shell per convertire il tuo numero in qualcosa che può andare in una sequenza di escape \ 0 funziona perfettamente. Più complesso con Unicode, poiché hai bisogno del supporto \ u nel tuo printf.
Peter Cordes

Sfortunatamente, Perl è una lingua dimenticata. Meglio è Python, che ora è presente in quasi tutte le macchine Linux. Inoltre, la domanda riguarda Shell-Bash e non altre piattaforme!
s3n0

7

Se vuoi salvare il valore ASCII del carattere: (l'ho fatto in BASH e ha funzionato)

{
char="A"

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

echo $testing}

uscita: 65


Ha funzionato, grazie. Volevo ottenere un numero intero (codice ASCII) da un carattere digitato. Ho fatto uno script: {read -n 1 c; echo $ (printf "% d" "'$ {c}")}
Fedro

4

Se converti 65in esadecimale è 0x41:

$ echo -e "\x41" A


se conosci il valore esadecimale per stampare il carattere ASCII$ printf "\x41"
katta

4

Per lettere maiuscole:

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

Produzione:

C

3

Ecco un altro modo per convertire 65 in LA (tramite ottale):

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

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

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

Per cercare in man bashper \'l'uso (anche se inutile in questo caso):

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

1

questo stampa tutti i caratteri "stampabili" della tua configurazione bash di base:

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

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

0

Ecco una soluzione senza eval$ () né ``:

ord () {
 local s
 printf -v s '\\%03o' $1
 printf "$s"
}

ord 65
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.