Pergunta

Eu gostaria de adicionar o crânio unicode e os ossos cruzados ao meu prompt de shell (especificamente o 'crânio e ossos cruzados' (U+2620)), mas não consigo descobrir o encantamento mágico para fazer o eco cuspindo, ou qualquer outro, Caráter Unicode de 4 dígitos. Os dois dígitos são fáceis. Por exemplo, echo -e " x55" ,.

Além das respostas abaixo, deve -se notar que, obviamente, seu terminal precisa suportar o Unicode para que a saída seja o que você espera. O GNOME-Terminal faz um bom trabalho nisso, mas não é necessariamente ativado por padrão.

No aplicativo Terminal do MacOS, vá para Preferências-> Encodings e escolha Unicode (UTF-8).

Foi útil?

Solução

No UTF-8, na verdade são 6 dígitos (ou 3 bytes).

$ printf '\xE2\x98\xA0'
☠

Para verificar como é codificado pelo console, use o HexDump:

$ printf ☠ | hexdump
0000000 98e2 00a0                              
0000003

Outras dicas

% echo -e '\u2620'     # \u takes four hexadecimal digits
☠
% echo -e '\U0001f602' # \U takes eight hexadecimal digits
😂

Isso funciona no ZSH (eu verifiquei a versão 4.3) e no Bash 4.2 ou mais recente.

Desde que seus editores de texto possam lidar com o Unicode (presumivelmente codificado no UTF-8), você pode inserir o ponto de código Unicode diretamente.

Por exemplo, no Vim editor de texto que você entraria no modo de inserção e pressionaria Ctrl + V + você e então o número do ponto de código como um número hexadecimal de 4 dígitos (pad com zeros, se necessário). Então você digitaria Ctrl + V + você 2 6 2 0. Ver: Qual é a maneira mais fácil de inserir caracteres Unicode em um documento?

Em uma festa de execução do terminal, você digitaria Ctrl+MUDANÇA+você e digite o ponto de código hexadecimal do personagem que você deseja. Durante a entrada, seu cursor deve mostrar um sublinhado u. O primeiro não dígito que você digita a entrada e renderiza o personagem. Então você pode imprimir U+2620 em Bash usando o seguinte:

echo Ctrl+MUDANÇA+você2620DIGITARDIGITAR

(O primeiro Enter Ensts Unicode Input, e o segundo executa o echo comando.)

Crédito: Pergunte a Ubuntu SE

Aqui está uma implementação totalmente interna de bash, sem fenda, tamanho ilimitado de caracteres Unicode.

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

A saída foi:

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

Basta colocar "☠" em seu script de shell. No local correto e em um console habilitado para unicode, ele imprimirá muito bem:

$ echo ☠
☠
$

Uma "solução alternativa" feia seria produzir a sequência UTF-8, mas isso também depende da codificação usada:

$ echo -e '\xE2\x98\xA0'
☠
$

Quick One-Liner para converter caracteres UTF-8 em seu formato de 3 bytes:

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

I'm using this:

$ echo -e '\u2620'
☠

This is pretty easier than searching a hex representation... I'm using this in my shell scripts. That works on gnome-term and urxvt AFAIK.

You may need to encode the code point as octal in order for prompt expansion to correctly decode it.

U+2620 encoded as UTF-8 is E2 98 A0.

So in Bash,

export PS1="\342\230\240"

will make your shell prompt into skull and bones.

Any of these three commands will print the character you want in a console, provided the console do accept UTF-8 characters (most current ones do):

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) ☠

After, you could copy and paste the actual glyph (image, character) to any (UTF-8 enabled) text editor.

If you need to see how such Unicode Code Point is encoded in UTF-8, use xxd (much better hex viewer than 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

Or, in HEX to avoid errors: 0xE2 0x98 0xA0. That is, the values between the space (HEX 20) and the Line-Feed (Hex 0A).

If you want a deep dive into converting numbers to chars: look here!

In bash to print a Unicode character to output use \x,\u or \U (first for 2 digit hex, second for 4 digit hex, third for any length)

echo -e '\U1f602'

I you want to assign it to a variable use $'...' syntax

x=$'\U1f602'
echo $x

The printf builtin (just as the coreutils' printf) knows the \u escape sequence which accepts 4-digit Unicode characters:

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

Test with Bash 4.2.37(1):

$ printf '\u2620\n'
☠

If you don't mind a Perl one-liner:

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

-CS enables UTF-8 decoding on input and UTF-8 encoding on output. -E evaluates the next argument as Perl, with modern features like say enabled. If you don't want a newline at the end, use print instead of say.

Sorry for reviving this old question. But when using bash there is a very easy approach to create Unicode codepoints from plain ASCII input, which even does not fork at all:

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; };

Use it as follows to define certain codepoints

unicode crossbones 0x2620
echo "$crossbones"

or to dump the first 65536 unicode codepoints to stdout (takes less than 2s on my machine. The additional space is to prevent certain characters to flow into each other due to shell's monospace font):

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

or to tell a little very typical parent's story (this needs Unicode 2010):

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

Explanation:

  • printf '\UXXXXXXXX' prints out any Unicode character
  • printf '\\U%08x' number prints \UXXXXXXXX with the number converted to Hex, this then is fed to another printf to actually print out the Unicode character
  • printf recognizes octal (0oct), hex (0xHEX) and decimal (0 or numbers starting with 1 to 9) as numbers, so you can choose whichever representation fits best
  • printf -v var .. gathers the output of printf into a variable, without fork (which tremendously speeds up things)
  • local variable is there to not pollute the global namespace
  • local -n var=other aliases var to other, such that assignment to var alters other. One interesting part here is, that var is part of the local namespace, while other is part of the global namespace.
    • Please note that there is no such thing as local or global namespace in bash. Variables are kept in the environment, and such are always global. Local just puts away the current value and restores it when the function is left again. Other functions called from within the function with local will still see the "local" value. This is a fundamentally different concept than all the normal scoping rules found in other languages (and what bash does is very powerful but can lead to errors if you are a programmer who is not aware of that).

Based on Stack Overflow questions Unix cut, remove first token and 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")

Output is the following.

Octal representation is following \0342\0230\0240
☠

Easy with a Python2/3 one-liner:

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

Results in:

Here is a list of all unicode emoji's available:

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

Example:

echo -e "\U1F304"
🌄

For get the ASCII value of this character use hexdump

echo -e "🌄" | hexdump -C

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

And then use the values informed in hex format

echo -e "\xF0\x9F\x8C\x84\x0A"
🌄

If hex value of unicode character is known

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

If the decimal value of a unicode character is known

declare -i U=2*4096+6*256+2*16
printf -vH "%x" $U              # convert to hex
printf "%b" "\u$H"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top