Stampa da decimale a carattere ASCII, il mio comando non emette come previsto


14

Volevo produrre una stringa di tutti i caratteri ASCII con il seguente comando

for i in `seq 32 127`; do printf "%c" $i; done

L'output del comando sopra è:

33333334444444444555555555566666666667777777777..............

È la prima cifra (da sinistra) di ciascun numero.

Guardando attraverso questo sito ho trovato la risposta al mio problema Come stampare tutti i caratteri ASCII stampabili nella CLI? , tuttavia non capisco ancora perché il mio frammento originale non produca i caratteri ASCII come previsto.


1
POSIX lo impone, ecco una comp.unix.shelldiscussione sul perché è la cosa giusta;)
sr_

@sr_ Grazie per aver sottolineato il thread. Aveva la spiegazione che stavo cercando.
Ifthikhan,

Risposte:


13

Non è possibile stampare direttamente i codici ascii usando il printf "%c" $isimile in C.

Devi prima convertire il valore decimale di i nel suo valore ottale e quindi devi stamparlo usando printfe mettendo \davanti ai rispettivi valori ottali.

Per stampare A, devi convertire il decimale 65 in ottale, ovvero 101, quindi devi stampare quel valore ottale come:

printf "\101\n"

Questo stamperà A.

Quindi devi modificarlo per:

for i in `seq 32 127`; do printf \\$(printf "%o" $i);done;

Ma usando awkpuoi stampare direttamente come in linguaggio C.

awk 'BEGIN{for(i=32;i<=127;i++)printf "%c",i}';echo

7
In bashe zshquesto può essere fatto senza il ciclo e senza il comando esterno: printf $(printf '\%o' {32..127}).
arte

@manatwork: ya esattamente..grazie mille per averlo sottolineato ..
pradeepchhetri

1
@pradeepchhetri: Grazie per la risposta dettagliata e sembrava coprire la maggior parte dei dettagli richiesti (quindi ho scelto la tua risposta). Tuttavia, immagino che abbia perso un'importante informazione che può essere trovata nel seguente messaggio su unix.derkeiler.com/Newsgroups/comp.unix.shell/2007-07/… . Afferma che "Gli operandi dell'argomento devono essere trattati come stringhe se il corrispondente
identificatore di

Non è (char)(127)backspace o qualcosa del genere. Qualunque cosa sia, appare come una delle caselle esadecimali o come si chiamano. Se vuoi solo il "stampabile" (cioè leggibile), vai a 126. Inoltre, bel pensiero con l'ottale. È intelligente; Stavo pensando in termini di esadecimali (come printf '\x%x; {32..126}... o 127, immagino, dal momento che lo avete fatto anche voi tutti), ma non funziona. Octal salva la giornata! :) Infine, @Ifthikhan, non sono sicuro di cosa intendi. awkutilizza spesso comandi in stile C e non viene %cutilizzato da nessun'altra parte . L'uso dei numeri ottali è diverso dall'uso dei caratteri a un byte.
Dylan,

3

%c Interpreta l'argomento associato come carattere: viene stampato solo il primo carattere di un determinato argomento

Sembra che tu abbia già un modo per stamparli, ma qui c'è una variante.

for i in `seq 32 127`; do printf "\x$(printf "%x" $i) $i"; done

0

Hai bisogno printf, ma solo una volta; puoi sostituire un uso printfcon le echosequenze di escape Bash più semplici ed efficienti più:

Con esagesimali:

for i in `seq 32 127`; do
  echo -ne \\x$(printf %02x $i)
done

Con ottali:

for i in `seq 32 127`; do
  echo -ne \\0$(printf %03o $i)
done
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.