it-swarm.com.de

Wie lässt sich ein 4-stelliges Unicode-Zeichen in Bash wiederholen?

Ich möchte den Unicode-Schädel und die gekreuzten Knochen zu meiner Shell-Eingabeaufforderung hinzufügen (insbesondere "SKULL AND CROSSBONES" (U + 2620)), aber ich kann nicht die magische Beschwörung herausfinden, die Echo spuckt. 4-stelliges Unicode-Zeichen. Zweistellige Zahlen sind einfach. Beispiel: echo -e "\ x55",.

Zusätzlich zu den nachstehenden Antworten sollte beachtet werden, dass Ihr Terminal natürlich Unicode unterstützen muss, damit die Ausgabe Ihren Erwartungen entspricht. gnome-terminal macht das gut, aber es ist nicht unbedingt standardmäßig aktiviert. 

Auf der macOS Terminal App gehen Sie zu Preferences-> Encodings und wählen Sie Unicode (UTF-8).

188
masukomi

In UTF-8 sind es eigentlich 6 Ziffern (oder 3 Bytes).

$ printf '\xE2\x98\xA0'
☠

Verwenden Sie hexdump, um zu überprüfen, wie es von der Konsole codiert wird:

$ printf ☠ | hexdump
0000000 98e2 00a0                              
0000003
202
vartec
% echo -e '\u2620'     # \u takes four hexadecimal digits
☠
% echo -e '\U0001f602' # \U takes eight hexadecimal digits
????

Dies funktioniert in Zsh (ich habe Version 4.3 überprüft) und in Bash 4.2 oder neuer.

78
Juliano

Solange Ihre Texteditoren mit Unicode (vermutlich in UTF-8 codiert) umgehen können, können Sie den Unicode-Codepunkt direkt eingeben.

Zum Beispiel würden Sie im Texteditor Vim in den Einfügemodus wechseln und drücken Ctrl + V + U und dann die Code-Punkt-Nummer als 4-stellige Hexadezimalzahl (ggf. mit Nullen auffüllen). Sie würden also tippen Ctrl + V + U262. Siehe: Wie lassen sich Unicode-Zeichen am einfachsten in ein Dokument einfügen?

An einem Terminal, auf dem Bash ausgeführt wird, geben Sie Folgendes ein CTRL+SHIFT+U und geben Sie den hexadezimalen Code des gewünschten Zeichens ein. Während der Eingabe sollte Ihr Cursor einen unterstrichenen uanzeigen. Die erste Ziffer, die Sie nicht eingeben, beendet die Eingabe und gibt das Zeichen wieder. So können Sie U + 2620 in Bash folgendermaßen drucken:

echoCTRL+SHIFT+U262ENTERENTER

(Die erste Eingabe beendet die Unicode-Eingabe und die zweite führt den Befehl echoaus.)

Gutschrift: Fragen Sie Ubuntu SE

66
RobM

Hier ist eine vollständig interne Bash-Implementierung, keine Gabelung, unbegrenzte Größe von Unicode-Zeichen.

fast_chr() {
    local __octal
    local __char
    printf -v __octal '%03o' $1
    printf -v __char \\$__octal
    REPLY=$__char
}

function unichr {
    local c=$1    # Ordinal of char
    local l=0    # Byte ctr
    local o=63    # Ceiling
    local p=128    # Accum. bits
    local s=''    # Output string

    (( c < 0x80 )) && { fast_chr "$c"; echo -n "$REPLY"; return; }

    while (( c > o )); do
        fast_chr $(( t = 0x80 | c & 0x3f ))
        s="$REPLY$s"
        (( c >>= 6, l++, p += o+1, o>>=1 ))
    done

    fast_chr $(( t = p | c ))
    echo -n "$REPLY$s"
}

## test harness
for (( i=0x2500; i<0x2600; i++ )); do
    unichr $i
done

Ausgabe war:

─━│┃┄┅┆┇┈┉┊┋┌┍┎┏
┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟
┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯
┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿
╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏
═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟
╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯
╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿
▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏
▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟
■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯
▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿
◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●
◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟
◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯
◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿
31
Orwellophile

Fügen Sie einfach "☠" in Ihr Shell-Skript ein. Im richtigen Gebietsschema und auf einer Unicode-fähigen Konsole wird der Druckvorgang problemlos ausgeführt:

$ echo ☠
☠
$

Eine hässliche "Problemumgehung" wäre die Ausgabe der UTF-8-Sequenz. Dies hängt jedoch auch von der verwendeten Codierung ab:

$ echo -e '\xE2\x98\xA0'
☠
$
13
Joachim Sauer

Schneller Einzeiler zum Konvertieren von UTF-8-Zeichen in das 3-Byte-Format:

var="$(echo -n '☠' | od -An -tx1)"; printf '\\x%s' ${var^^}; echo
10
David King

Ich benutze das:

$ echo -e '\u2620'
☠

Das ist ziemlich einfacher als das Suchen einer Hex-Darstellung ... Ich verwende dies in meinen Shell-Skripten. Das funktioniert auf gnome-term und urxvt AFAIK.

8
Metal3d

Möglicherweise müssen Sie den Codepunkt als Oktal codieren, damit die Eingabeaufforderung von Expansion korrekt decodiert wird.

U + 2620, codiert als UTF-8, ist E2 98 A0.

Also in Bash,

export PS1="\342\230\240"

macht Ihre Shell Prompt in Schädel und Knochen.

7
cms

Jeder dieser drei Befehle druckt das gewünschte Zeichen in einer Konsole, vorausgesetzt, die Konsole akzeptiert UTF-8 Zeichen (die meisten aktuellen tun dies):

echo -e "SKULL AND CROSSBONES (U+2620) \U02620"
echo $'SKULL AND CROSSBONES (U+2620) \U02620'
printf "%b" "SKULL AND CROSSBONES (U+2620) \U02620\n"

SKULL AND CROSSBONES (U+2620) ☠

Anschließend können Sie das tatsächliche Symbol (Bild, Zeichen) in einen beliebigen (UTF-8-fähigen) Texteditor kopieren und einfügen.

Wenn Sie sehen möchten, wie ein solcher Unicode-Codepunkt in UTF-8 codiert ist, verwenden Sie xxd (viel besser als Hex-Viewer):

echo $'(U+2620) \U02620' | xxd
0000000: 2855 2b32 3632 3029 20e2 98a0 0a         (U+2620) ....

That means that the UTF8 encoding is: e2 98 a0

Oder in HEX, um Fehler zu vermeiden: 0xE2 0x98 0xA0. Das sind die Werte zwischen dem Leerzeichen (HEX 20) und dem Zeilenvorschub (Hex 0A).

Wenn Sie tief in die Umwandlung von Zahlen in Zeichen eintauchen möchten: schauen Sie hier !

4
user2350426

Wenn Ihnen ein Perl-Einzeiler nichts ausmacht:

$ Perl -CS -E 'say "\x{2620}"'
☠

-CS aktiviert die UTF-8-Dekodierung am Eingang und die UTF-8-Kodierung am Ausgang. -E wertet das nächste Argument als Perl aus, wobei moderne Funktionen wie say aktiviert sind. Wenn Sie am Ende keine neue Zeile wünschen, verwenden Sie print anstelle von say.

3
Flimm

Die printf builtin (genau wie die printf der coreutils) kennt die \u-Escape-Sequenz, die 4-stellige Unicode-Zeichen akzeptiert:

   \uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)

Test mit Bash 4.2.37 (1):

$ printf '\u2620\n'
☠
3
Michael Jaros

Um ein Unicode-Zeichen für die Ausgabe zu drucken, verwenden Sie\x,\u oder\U (zuerst für 2-stellige Hex-Zeichen, zweitens für 4-stellige Hex-Zeichen, 3. für beliebige Länge)

echo -e '\U1f602'

Wenn Sie es einer Variablen zuweisen möchten, verwenden Sie die Syntax $ '...'

x=$'\U1f602'
echo $x
3
user2622016

Gestützt auf Fragen zum Stack Overflow Unix-Cut, entferne zuerst das Token und https://stackoverflow.com/a/15903654/781312:

(octal=$(echo -n ☠ | od -t o1 | head -1 | cut -d' ' -f2- | sed -e 's#\([0-9]\+\) *#\\0\1#g')
echo Octal representation is following $octal
echo -e "$octal")

Ausgabe ist die folgende.

Octal representation is following \0342\0230\0240
☠
2
test30

Entschuldigung, dass Sie diese alte Frage wiederbelebt haben. Bei der Verwendung von bash ist es jedoch ein sehr einfacher Weg, Unicode-Codepunkte aus einfachen ASCII -Eingaben zu erstellen, die gerade gar nicht überhaupt verzweigen: /

unicode() { local -n a="$1"; local c; printf -vc '\\U%08x' "$2"; printf -va "$c"; }
unicodes() { local a c; for a; do printf -vc '\\U%08x' "$a"; printf "$c"; done; };

Verwenden Sie es wie folgt, um bestimmte Codepunkte zu definieren

unicode crossbones 0x2620
echo "$crossbones"

oder um die ersten 65536-Unicode-Codepunkte in stdout zu speichern (nimmt auf meinem Computer weniger als 2 Sekunden in Anspruch. Der zusätzliche Speicherplatz verhindert, dass bestimmte Zeichen aufgrund der Monospace-Schriftart von Shell ineinanderfließen):

for a in {0..65535}; do unicodes "$a"; printf ' '; done

oder um eine sehr typische Geschichte eines Elternteils zu erzählen (dies erfordert Unicode 2010):

unicodes 0x1F6BC 32 43 32 0x1F62D 32 32 43 32 0x1F37C 32 61 32 0x263A 32 32 43 32 0x1F4A9 10

Erläuterung:

  • printf '\UXXXXXXXX' druckt beliebige Unicode-Zeichen
  • printf '\\U%08x' number druckt \UXXXXXXXX mit der in Hex konvertierten Zahl. Diese wird dann einer anderen printf zugeführt, um das Unicode-Zeichen tatsächlich auszudrucken
  • printf erkennt Oktal (0oct), Hex (0xHEX) und Dezimalzahl (0 oder Zahlen beginnend mit 1 bis 9) als Zahlen. Sie können also wählen, welche Darstellung am besten passt
  • printf -v var .. sammelt die Ausgabe von printf in eine Variable, ohne Verzweigung (was die Dinge enorm beschleunigt)
  • local variable dient dazu, den globalen Namespace nicht zu verschmutzen
  • local -n var=other-Aliase var in other, so dass die Zuordnung zu varother ändert. Interessant dabei ist, dass var Teil des lokalen Namensraums ist, während other Teil des globalen Namensraums ist .
    • Bitte beachten Sie, dass es in local keinen Namespace global oder bash gibt. Variablen werden in der Umgebung aufbewahrt und sind immer global. Local legt den aktuellen Wert einfach zurück und stellt ihn wieder her, wenn die Funktion wieder verlassen wird. Andere Funktionen, die innerhalb der Funktion mit local aufgerufen werden, sehen weiterhin den Wert "local". Dies ist ein grundlegend anderes Konzept als alle normalen Bereichsregeln, die in anderen Sprachen zu finden sind (und bash ist sehr mächtig, kann jedoch zu Fehlern führen, wenn Sie ein Programmierer sind, der sich dessen nicht bewusst ist).
2
Tino

Einfach mit einem Python2/3-Einliner:

$ python -c 'print u"\u2620"'    # python2
$ python3 -c 'print(u"\u2620")'  # python3

Ergebnisse in:

2
Chris Johnson

Hier ist eine Liste aller verfügbaren Unicode-Emojis:

https://en.wikipedia.org/wiki/Emoji#Unicode_blocks

Beispiel:

echo -e "\U1F304"
????

Verwenden Sie hexdump, um den ASCII -Wert dieses Zeichens abzurufen

echo -e "????" | hexdump -C

00000000  f0 9f 8c 84 0a                                    |.....|
00000005

Verwenden Sie dann die im Hex-Format angegebenen Werte

echo -e "\xF0\x9F\x8C\x84\x0A"
????
0

Wenn der Hex-Wert des Unicode-Zeichens bekannt ist

H="2620"
printf "%b" "\u$H"

Wenn der Dezimalwert eines Unicode-Zeichens bekannt ist

declare -i U=2*4096+6*256+2*16
printf -vH "%x" $U              # convert to hex
printf "%b" "\u$H"
0
philcolbourn