Wie drucke ich ein ASCII-Zeichen mit verschiedenen Codepunkten in Bash?

Wie drucke ich ein ASCII-Zeichen mit verschiedenen Codepunkten in Bash?

In der ASCII-Tabelle gibt es das Zeichen „J“, das über Codepunkte in verschiedenen Zahlensystemen verfügt:

Oct   Dec   Hex   Char
112   74    4A    J

Es ist möglich, dieses Zeichen mit einem oktalen Codepunkt auszudrucken, indem Sie printf '\112'oder drucken echo $'\112'. Wie drucke ich dasselbe Zeichen mit dezimaler und hexadezimaler Codepunktdarstellung?

Antwort1

Verhexen:

printf '\x4a'

Dez:

printf "\\$(printf %o 74)"

Alternative für Hex :-)

xxd -r <<<'0 4a'

Antwort2

Im Allgemeinen kann die Shell Hex-, Oktal- und Dezimalzahlen in Variablen verstehen, vorausgesetzt, sie wurden wie folgt definiert integers:

$ declare -i v1 v2 v3 v4 v5 v6 v7
$ v1=0112
$ v2=74
$ v3=0x4a
$ v4=8#112
$ v5=10#74
$ v6=16#4a
$ v7=18#gg
echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

Oder sie sind das Ergebnis einer „Arithmetischen Erweiterung“:

$ : $(( v1=0112, v2=74, v3=0x4a, v4=8#112, v5=10#74, v6=16#4a, v7=18#gg ))
$ echo "$v1 $v2 $v3 $v4 $v5 $v6 $v7"
74 74 74 74 74 74 304

Sie benötigen also nur eine Möglichkeit, das Zeichen zu drucken, das zu einem Variablenwert gehört.
Aber hier sind zwei Möglichkeiten:

$ var=$((0x65))
$ printf '%b\n' "\\$(printf '0%o' "$var")"
e

$ declare -i var
$ var=0x65; printf '%b\n' "\U$(printf '%08x' "$var")"
e

Die beiden printf-Funktionen werden benötigt, eine zum Umwandeln des Werts in eine hexadezimale Zeichenfolge und die zweite zum eigentlichen Drucken des Zeichens.

Der zweite druckt jeden UNICODE-Punkt (wenn Ihre Konsole richtig eingestellt ist).
Beispiel:

$ var=0x2603; printf '%b\n' "\U$(printf '%08x' "$var")"

Ein Schneemann.

Das Zeichen, das eine UTF-8-Darstellung hat, f0 9f 90 aeist 0x1F42E. Suche nach cow face site:fileformat.infotobekomme es:

$ var=0x1F42F; printf '%b\n' "\U$(printf '%08x' "$var")"

Antwort3

Dezimal:

chr() {
    local c
    for c
    do
        printf "\\$((c/64*100+c%64/8*10+c%8))"
    done
}

chr 74

Verhexen:

chr $((16#4a))

Die Funktion kann Sequenzen ausführen:

$ chr 74 75 76; echo
JKL
$

Antwort4

Wenn Sie eine Liste von Zahlen konvertieren möchten und einen Funktionsaufruf sowie das Erstellen einer Subshell für jedes Zeichen vermeiden möchten, können Sie den ASCII-Satz im Voraus definieren:

ascii=$(for x in {0..9} {A..F}; do for y in {0..9} {A..F}; do echo -ne "\x$x$y"; done; done)

Beachten Sie, dass Nullzeichen ausgeschlossen sind und daher jedes Zeichen um 1 verschoben ist.

Verwenden Sie dann etwas wie das Folgende (nimmt an, dass 1 Zahl pro Zeile gilt):

while read c; do out+="${ascii:$c-1:1}"; done <<< "$in"
echo "$out"

verwandte Informationen