Wenn ich ein Dezimal- oder ASCII-Zeichen drucke, wird mein Befehl nicht wie vorgesehen ausgegeben

14

Ich wollte mit dem folgenden Befehl eine Zeichenfolge aller ASCII-Zeichen ausgeben

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

Die Ausgabe des obigen Befehls lautet:

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

Es ist die erste (von links) Ziffer jeder Zahl.

Beim Durchsuchen dieser Website bin ich auf die Antwort auf mein Problem gestoßen. Wie drucke ich alle druckbaren ASCII-Zeichen in der CLI? Ich verstehe jedoch immer noch nicht, warum mein Original-Snippet die ASCII-Zeichen nicht wie vorgesehen ausgibt.

Ifthikhan
quelle
1
POSIX schreibt dies vor. Hier ist ein comp.unix.shellThread darüber, warum es das Richtige ist;)
sr_
@sr_ Danke für den Hinweis auf den Thread. Es hatte die Erklärung, nach der ich gesucht hatte.
Ifthikhan

Antworten:

13

Sie können die ASCII-Codes nicht direkt drucken, indem Sie printf "%c" $iin C das Gleiche verwenden .

Sie müssen zuerst den Dezimalwert von i in den Oktalwert umwandeln und dann mit printfund \vor den jeweiligen Oktalwerten ausgeben.

Um zu drucken A, müssen Sie die Dezimalzahl 65 in eine Oktalzahl konvertieren, dh 101, und dann müssen Sie diesen Oktalwert wie folgt drucken:

printf "\101\n"

Dies wird gedruckt A.

Sie müssen es also ändern, um:

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

Mit können awkSie jedoch direkt wie in C-Sprache drucken

awk 'BEGIN{for(i=32;i<=127;i++)printf "%c",i}';echo
pradeepchhetri
quelle
7
In bashund zshdies ohne die Schleife und ohne den externen Befehl: printf $(printf '\%o' {32..127}).
Manatwork
@ Manatwork: ya genau .. vielen Dank für den Hinweis ..
pradeepchhetri
1
@pradeepchhetri: Vielen Dank für die ausführliche Antwort und es schien, die meisten erforderlichen Details abzudecken (daher wähle ich Ihre Antwort). Ich vermute jedoch, dass eine wichtige Information übersehen wurde, die in der folgenden Nachricht unter unix.derkeiler.com/Newsgroups/comp.unix.shell/2007-07/… zu finden ist . Darin heißt es: "Die Argumentoperanden werden als Zeichenfolgen behandelt, wenn der entsprechende Konvertierungsspezifizierer b, c oder s ist ..."
Ifthikhan
Ist nicht (char)(127)Rücktaste oder so ähnlich. Was auch immer es ist, es erscheint als eine der Hexboxen oder wie auch immer sie heißen. Wenn Sie nur die "druckbare" (dh lesbare) möchten, gehen Sie einfach auf 126. Auch schön mit dem Oktal gedacht. Das ist schlau; Ich habe hexadezimal gedacht (wie printf '\x%x; {32..126}... oder 127, ich denke, da Sie alle es auch getan haben), aber es funktioniert nicht. Oktal rettet den Tag! :) Schließlich @Ifthikhan, ich bin nicht sicher, was du meinst. awkverwendet häufig C-Befehle und wird nirgendwo anders %cverwendet. Die Verwendung von Oktalzahlen unterscheidet sich von der Verwendung von Ein-Byte-Zeichen.
Dylan
3

%c Interpretiert das zugehörige Argument als Zeichen: Es wird nur das erste Zeichen eines gegebenen Arguments gedruckt

Sie scheinen bereits eine Möglichkeit zum Drucken zu haben, aber hier ist eine Variante.

for i in `seq 32 127`; do printf "\x$(printf "%x" $i) $i"; done
Peter.O
quelle
0

Sie brauchen printf, aber nur einmal; Sie können eine Verwendung printfdurch die einfacheren und effizienteren echoPlus-Bash-Escape-Sequenzen ersetzen :

Mit hexagesimalen:

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

Mit Oktalen:

for i in `seq 32 127`; do
  echo -ne \\0$(printf %03o $i)
done
Luchostein
quelle