No bash, como posso converter um ponto de código Unicode [0-9A-F] em um caractere imprimível?

20

Eu tenho uma lista de pontos de código Unicode, mas não conheço uma maneira "simples" de converter esses valores hexadecimais nos caracteres reais que eles representam ...

Ouvi dizer que zsh tem echo -e '\u0965' , mas eu uso bash 4.1.

Existe algo tão simples quanto o método zsh, para bash?

    
por Peter.O 29.04.2011 / 06:20

6 respostas

13

Você pode usar o eco do bash ou o / bin / echo do GNU coreutils em combinação com o iconv:

echo -ne '\x09\x65' | iconv -f utf-16be

Por padrão, o iconv converte em sua codificação de locales. Talvez mais portável do que depender de um comando específico de shell ou eco seja o Perl. A maioria dos sistemas UNIX que conheço tem Perl disponível e até tem várias portas Windows.

perl -C -e 'print chr 0x0965'

Na maioria das vezes, quando preciso fazer isso, estou em um editor como o Vim / GVim, que tem suporte integrado. Enquanto estiver no modo de inserção, pressione Ctrl-V seguido por u e digite quatro caracteres hexadecimais. Se você quiser um caractere além de U + FFFF, use um U maiúsculo e digite 8 caracteres hexadecimais. O Vim também suporta personalizações fáceis de criar mapas de teclado. Converte uma série de caracteres em outro símbolo. Por exemplo, eu tenho um mapa de teclado que desenvolvi chamado www, ele converte TM para ™, (C) para ©, (R) para ® e assim por diante. Eu também tenho um mapa de chaves para o Klingon para quando isso for necessário. Tenho certeza que o Emacs tem algo parecido. Se você estiver em um aplicativo GTK + que inclui o GVim e o Terminal GNOME, você pode tentar Control-Shift-u seguido de 4 caracteres hexadecimais para criar um caractere Unicode. Tenho certeza que o KDE / Qt tem algo parecido.

ATUALIZAÇÃO: A partir do Bash 4.2, parece ser um recurso embutido agora:

echo $'\u0965'

UPDATE: Além disso, hoje em dia, um exemplo do Python provavelmente seria preferido ao Perl. Isso funciona no Python 2 e 3:

python -c 'print(u"\u0965")'
    
por 29.04.2011 / 10:06
12

Bash 4.2 (lançado em 2011) adicionou suporte para echo -e '\u0965' , printf '\u0965' , printf %b '\u0965' e echo $'\u0965' também funcionam.

link :

o   $'...', echo, and printf understand \uXXXX and \UXXXXXXXX escape sequences.
    
por 14.03.2013 / 13:48
4

Se você tem coreutils GNU, tente printf :

$ printf '\u0965\n'
॥

echo pode fazer o trabalho se seu console estiver usando o UTF-8 e você tiver a codificação UTF-8:

$ echo -e '\xE0\xA5\xA5'

Você pode encontrar uma tabela de codificações hexadecimal Unicode para UTF-8 aqui: link . Você pode converter os pontos de código Unicode em hexadecimais usando várias linguagens de script. Aqui está um exemplo usando python:

python -c "print(unichr(int('0965', 16)).encode('utf-8').encode('hex'))"

O seguinte é um script Perl que irá converter argumentos para o valor hexadecimal correto (muitos parênteses desnecessários aqui):

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Encode;

foreach (@ARGV) {
    say unpack('H*', encode('utf8', chr(hex($_))))
}

Por exemplo,

./uni2utf 0965
e0a5a5

Claro, se você tiver Perl ou Python, também poderá usá-los para imprimir os caracteres.

    
por 29.04.2011 / 09:13
2

UPDATE: Aqui está uma maneira bash de fazer um único valor Unicode ... (por "bash" quero dizer: não usando qualquer outra linguagem de script) .. graças a Gilles por uma sugestão neste askubuntu Q / A .
De acordo com este link : recode (Obsoletes iconv, dos2unix, unix2dos) .. Editar: mas de acordo com o comentário abaixo, "obsoletos" pode significar apenas "alternativa"

      echo -n 0x0965 |recode UTF-16BE/x4..UTF-8

Aqui está um método para processar um despejo hexadecimal raw como entrada (ou seja, sem prefixos com escape, como \ u0965 e não \ x09 \ x65) ..
xxd is um utilitário de despejo hexadecimal (empacotado com vim-common ) que pode reverter um dump hexadecimal bruto para os caracteres que o dump representa ... Codepoints Unicode são UTF-16BigEndian, que é exatamente o que um Hex-dump é ..
xxd no modo de reversão aceita um fluxo de valores hexadecimais com quebras de linha.que são ignorados.

Esse script cria um fluxo UTF-16BE, que depois reverte para os caracteres originais.
A última linha contém os dois comandos necessários; xxd e iconv

for line in \
  "Matsuo Basho (1644-1694)" \
  "  pond" \
  "  frog jumps in" \
  "  plop!"
do 
  echo "$line" |iconv -f "$(locale charmap)" -t "UTF-16BE" |xxd -ps -u 
done |
#    (---this is the **revert** code---) 
tee >(xxd -p -u -r |iconv -f "UTF-16BE") ;echo

Aqui está a saída (mostrando a entrada hexadecimal UTF-16BE, primeiro).
Nota; xxd segmenta sua própria saída com uma nova linha em 60 dígitos hexadecimais ... A opção de reverter ignora essas novas linhas ... ele ignora todas as novas linhas (como se não fossem dígitos hexadecimais).

004D0061007400730075006F00200042006100730068006F002000280031
003600340034002D00310036003900340029000A
002000200070006F006E0064000A
0020002000660072006F00670020006A0075006D0070007300200069006E
000A
002000200070006C006F00700021000A

Matsuo Basho (1644-1694)
  pond
  frog jumps in
  plop!
    
por 29.04.2011 / 10:58
1

Assumindo que a codificação padrão para o seu sistema operacional é UTF-8 (true para a maioria das distribuições atuais) então você pode usar o bash diretamente para converter qualquer ponto de código UNICODE:

echo -e "Unicode Character 'DEVANAGARI DOUBLE DANDA' (U+0965) \U0965"

É claro que o glifo só aparecerá corretamente se você tiver a fonte correta. A partir do ano 4.3 todos os pontos de código funcionarão corretamente. E essas duas opções internas também funcionarão:

printf "%b" "Unicode Character (U+0965) \U0965 \n"
echo $'Unicode Character (U+0965) \U0965'

Observe que, para o bash 4.2, os pontos de código Unicode de 0x80 a 0xFF estão codificados incorretamente (erro bash). Para contornar este problema, você deve dar uma olhada no programa em este site (também bom para um exame profundo da questão da convertendo números em chars.

    
por 18.02.2015 / 04:32
0

Usando a substituição de padrão na versão bash 4.2 (e superior):

${parameter/pattern/string}

como descrito aqui link

UNICODE_HEX="U+02211"
printf ${UNICODE_HEX/U+/"\U"}
∑

UNICODE_HEX="U+03BB"
printf ${UNICODE_HEX/U+/"\U"}
λ         
    
por 21.06.2017 / 15:47

Tags