Wie kann man einen 4-stelligen Unicode-Charakter in Bash wiederholen?
-
03-07-2019 - |
Frage
Ich möchte den Unicode -Schädel und die Kreuzbeine meiner Shell -Eingabeaufforderung (insbesondere die Schädel und Kreuzbeine '(U+2620)) hinzufügen, aber ich kann die magische Beschwörung nicht herausfinden, um Echo auszuspucken, oder andere. 4-stelliges Unicode-Zeichen. Zwei -stellige sind einfach. Zum Beispiel echo -e " x55" ,.
Zusätzlich zu den folgenden Antworten sollte beachtet werden, dass Ihr Terminal offensichtlich Unicode für die Ausgabe unterstützen muss, die Sie erwarten. Gnome-terminal leistet dies gute Arbeit, aber es wird nicht unbedingt standardmäßig aktiviert.
In der Terminal-App von MacOS wechseln Sie zu Einstellungen-> Codierungen und wählen Sie Unicode (UTF-8).
Lösung
In UTF-8 sind es tatsächlich 6 Ziffern (oder 3 Bytes).
$ printf '\xE2\x98\xA0'
☠
Um zu überprüfen, wie es von der Konsole kodiert wird, verwenden Sie Hexdump:
$ printf ☠ | hexdump
0000000 98e2 00a0
0000003
Andere Tipps
% 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.
Solange Ihre Text-Editoren mit Unicode (vermutlich in UTF-8 codiert) fertig werden können, können Sie den Unicode-Codepunkt direkt eingeben.
Zum Beispiel in der Vim Text-Editor Sie haben den Einfügungsmodus eingeben und drücken Strg + V + U und dann die Code-Punkt-Nummer als 4-stellige Hexadezimalzahl (PAD mit Nullen). Sie würden also tippen Strg + V + U 2 6 2 0. Sehen: Was ist der einfachste Weg, um Unicode -Zeichen in ein Dokument einzufügen?
An einem Terminal laufenden Bash würden Sie tippen Strg+WECHSEL+U und geben Sie den Hexadezimalcodepunkt des gewünschten Charakters ein. Während der Eingabe sollte Ihr Cursor eine unterstrichene zeigen u
. Das erste Nicht-Digit, den Sie beenden, geben Eingaben ein und rendert den Charakter. Sie können also in der Lage sein, U+2620 in Bash mit Folgendem zu drucken:
echÖ Strg+WECHSEL+U2620EINTRETENEINTRETEN
(Die erste Eingabetaste beendet die Unicode -Eingabe, und die zweite wird die ausgeführt echo
Befehl.)
Anerkennung: Fragen Sie Ubuntu Se
Hier ist eine vollständig interne Bash -Implementierung, keine unbegrenzte Größe der 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:
─━│┃┄┅┆┇┈┉┊┋┌┍┎┏
┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟
┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯
┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿
╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏
═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟
╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯
╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿
▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏
▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟
■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯
▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿
◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●
◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟
◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯
◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿
Setzen Sie einfach "☠" in Ihr Shell -Skript. Im richtigen Gebietsschema und auf einer unicode-fähigen Konsole wird es gut gedruckt:
$ echo ☠
☠
$
Eine hässliche "Problemumgehung" wäre, die UTF-8-Sequenz auszugeben, aber das hängt auch von der verwendeten Codierung ab:
$ echo -e '\xE2\x98\xA0'
☠
$
Schneller Ein-Liner, um UTF-8-Zeichen in ihr 3-Byte-Format umzuwandeln:
var="$(echo -n '☠' | od -An -tx1)"; printf '\\x%s' ${var^^}; echo
Ich benutze das:
$ echo -e '\u2620'
☠
Dies ist ziemlich einfacher als die Suche nach einer Hex -Darstellung ... Ich verwende dies in meinen Shell -Skripten. Das funktioniert auf Gnom-Term und Urxvt Afaik.
Möglicherweise müssen Sie den Codepunkt als Oktal codieren, damit die Umlauferweiterung korrekt entschlüsselt wird.
U+2620 als UTF-8 codiert ist E2 98 A0.
Also in Bash,
export PS1="\342\230\240"
Wird Ihre Muschel in Schädel und Knochen einschalten.
Jeder dieser drei Befehle druckt das gewünschte Zeichen in einer Konsole, vorausgesetzt, die Konsole akzeptiert UTF-8 Charaktere (am aktuellsten tun):
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) ☠
Danach können Sie das tatsächliche Glyphe (Bild, Zeichen) in einen beliebigen (UTF-8-fähigen) Texteditor kopieren und einfügen.
Wenn Sie sehen müssen, wie ein solcher Unicode-Codepunkt in UTF-8 codiert ist, verwenden Sie XXD (viel besserer Hex-Viewer als OD):
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 heißt, die Werte zwischen dem Raum (Hex 20) und der Linienfutter (Hex 0a).
Wenn Sie einen tiefen Eintauchen in die Umwandlung von Zahlen in Chars wünschen: Schau hier!
In Bash zum Ausdrucken eines Unicode -Zeichens zum Ausgang Verwenden Sie x, u oder u (zuerst für 2 -stelliges Hex, zweiter für 4 -stellige Hex, dritter für jede Länge)
echo -e '\U1f602'
I Sie möchten es einer Variablen verwenden. Verwenden Sie $ '...' Syntax
x=$'\U1f602'
echo $x
Das printf
gebaut (genau wie die Coreutils ' printf
) 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'
☠
Wenn es Ihnen nichts ausmacht, einen Perl-One-Liner:
$ perl -CS -E 'say "\x{2620}"'
☠
-CS
Aktiviert die UTF-8-Decodierung der Eingabe- und UTF-8-Codierung der Ausgabe. -E
bewertet das nächste Argument als Perl mit modernen Merkmalen wie say
aktiviert. Wenn Sie am Ende keine neue Zeile wollen, verwenden Sie print
Anstatt von say
.
Entschuldigung für die Wiederbelebung dieser alten Frage. Aber wenn ich benutze bash
Es gibt einen sehr einfachen Ansatz, um Unicode -CodePoints aus der einfachen ASCII -Eingabe zu erstellen, die sogar sogar gib nicht überhaupt:
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 CodePoints zu definieren
unicode crossbones 0x2620
echo "$crossbones"
oder um die ersten 65536 Unicode -CodePoints in STDOut abzugeben (dauert weniger als 2s auf meiner Maschine. Der zusätzliche Raum besteht darin, zu verhindern, dass bestimmte Zeichen aufgrund der Monospace -Schrift von Shell ineinander fließen):
for a in {0..65535}; do unicodes "$a"; printf ' '; done
Oder um eine kleine sehr typische Geschichte der Eltern 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 jeden Unicode -Charakter ausprintf '\\U%08x' number
Drucke\UXXXXXXXX
Mit der in Hex konvertierten Zahl wird dies dann an einen anderen gefüttertprintf
Um den Unicode -Charakter tatsächlich auszudruckenprintf
Erkennt Octal (0okt), Hex (0xhex) und Dezimal (0 oder Zahlen, beginnend mit 1 bis 9) als Zahlen, sodass Sie auswählen können, welche Darstellung am besten passtprintf -v var ..
sammelt die Ausgabe vonprintf
in eine Variable, ohne Gabel (Was die Dinge enorm beschleunigt)local variable
Gibt es nicht, um den globalen Namespace nicht zu verschmutzen?local -n var=other
Aliasevar
zuother
, so dass die Zuordnung zuvar
verändertother
. Ein interessanter Teil hier ist das, dasvar
ist Teil des lokalen Namespace währendother
ist Teil des globalen Namespace.- Bitte beachten Sie, dass es keine gibt, wie
local
oderglobal
Namespace inbash
. Variablen werden in der Umwelt gehalten und solche sind immer global. Lokal legt nur den aktuellen Wert weg und stellt ihn wieder her, wenn die Funktion wieder übrig bleibt. Andere Funktionen, die von innerhalb der Funktion mit aufgerufen werdenlocal
Wird immer noch den "lokalen" Wert sehen. Dies ist ein grundlegend anderes Konzept als alle normalen Scoping -Regeln in anderen Sprachen (und wasbash
ist sehr leistungsstark, kann aber zu Fehlern führen, wenn Sie ein Programmierer sind, der sich dessen nicht bewusst ist).
- Bitte beachten Sie, dass es keine gibt, wie
Basierend auf Stack -Überlauffragen Unix Cut, First Token entfernen 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
☠
Einfach mit einem Python2/3-One-Liner:
$ python -c 'print u"\u2620"' # python2
$ python3 -c 'print(u"\u2620")' # python3
Führt zu:
☠
Hier finden Sie eine Liste aller verfügbaren Unicode -Emojis:
https://en.wikipedia.org/wiki/emoji#unicode_blocks
Beispiel:
echo -e "\U1F304"
🌄
Um den ASCII -Wert dieses Charakters zu erhalten, verwenden Sie Hexdump
echo -e "🌄" | hexdump -C
00000000 f0 9f 8c 84 0a |.....|
00000005
Und verwenden Sie dann die im HEX -Format informierten Werte
echo -e "\xF0\x9F\x8C\x84\x0A"
🌄
Wenn der HEX -Wert des Unicode -Charakters 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"