force bash script para combinar nomes de arquivos com caracteres especiais em diferentes codificações

0

Eu tenho um script bash para comparar nomes de arquivos em diferentes locais. Eles têm caracteres especiais nos nomes de arquivos que estão em duas codificações diferentes, então meu script não corresponde a esses arquivos específicos.

Há algo que eu possa fazer para fazer o bash combiná-los?

Eles são codificados como utf8 e como TIS-620 Exemplos de nomes de arquivos em utf8 e TIS-620, respectivamente Löffler e Löffler

exemplo de script:

for i in /dir1/*; do
if [ ! -h "$i" ]; then
[ -d "/dir2/${i##*/}" ]
fi

usando unum Eu posso esta informação:

versão utf8 de ö

Octal  Decimal      Hex        HTML    Character   Unicode
0366      246     0xF6      ö    "ö"         LATIN SMALL LETTER O WITH DIAERESIS

Versão TIS-620 de ö

Octal  Decimal      Hex        HTML    Character   Unicode
0157      111     0x6F      o    "o"         LATIN SMALL LETTER O
01410      776    0x308      ̈    "̈"         COMBINING DIAERESIS

EDITAR:

Eu descobri o que causou a incompatibilidade, em primeiro lugar, uma ferramenta usando a normalização UTF. Eu ainda gostaria de saber como combinar o mesmo personagem em diferentes codificações. Outra maneira de colocar isso seria dizer, como posso usar a normalização UTF em linha para scripts BASH?

    
por jakethedog 10.07.2017 / 11:06

1 resposta

0

Acredito que você precise comparar alguns "textos" codificados na página de códigos do TIS-620 (em tailandês ) com a codificação utf8 (universal) equivalente.

Bem, como a codificação mais universal (que codificará tantos caracteres quanto UTF-32) é utf8, devemos converter a codificação mais local TIS-620 para ela.

A ferramenta usual de conversão de codificação é iconv . Com essa ferramenta, você pode fazer:

$ printf '\xC1' | iconv -f TIS620 -t utf8
ม

E veja (se seu terminal aceita utf8) o caractere ม. O caractere tem um valor de C1 olhando para a tabela no TIS-620 da wikipedia.

Ou, para "ver" os bytes que fazem esse caractere (no utf8):

$ printf '\xC1' | iconv -f TIS620 -t utf8 | od -vAn -tx1
e0 b8 a1

Quais são os 3 bytes que resultam ao codificar o caractere com o número de ponto de código Unicode U0E21 de fileformat ou, também em www.utf8-chartable .de :

U+0E21  ม   e0 b8 a1    THAI CHARACTER MO MA

A lista de codificações disponíveis para o TIS620 em iconv é:

$ iconv -l | grep 620
TIS-620//
TIS620-0//
TIS620.2529-1//
TIS620.2533-0//
TIS620//

Escolha um que corresponda à codificação dos seus nomes de arquivo.

No entanto, não consigo encontrar uma trema ö em tailandês.
A página TIS620 tailandesa Ou até mesmo o (muito antigo) tradução de tailandês para ISO / IEC 10646-1: 1993 não mostre a existência de um o com umlalaut em tailandês.

Você poderia, por favor, editar novamente sua pergunta?

Sobre trema

Vamos supor que o console / terminal esteja configurado para entender o utf8. E vamos criar três nomes de arquivos em um diretório com diferentes tremas.

  1. Latin ö (como um ponto de código unicode) (representado como 0xC3 0xB6 no utf8). LETRA PEQUENA COM O DIAERESIS (U + 00F6)
    Latim ö

    $ printf 'L\xC3\xB6ffler'; echo
    Löffler
    
  2. Latin ö (como uma letra o seguida por uma diaresis) (é 0x6F 0xCC 0x88 em utf8). COMBINANDO DIAERESE (U + 0308)
    Diaeresis

    $ printf 'Lo\xCC\x88ffler'; echo
    Löffler
    
  3. E: cirílico com diaerese (é 0xD3 0xA7 em utf-8) CIRÚRICO CARTA PEQUENA O COM DIAERESE (U + 04E7)
    Cirílico O com trema

    $ printf 'L\xD3\xA7ffler'; echo
    Lӧffler
    

Para criar os três arquivos com esses nomes de arquivos, você pode usar:

$ touch $(printf 'L\xC3\xB6ffler Lo\xCC\x88ffler L\xD3\xA7ffler')

Uma forma de listar esses arquivos é usar um Glob que corresponda (somente esses arquivos).
Nesse caso, o ffler é exibido em todos os arquivos.

$ echo *ffler
Löffler Löffler Lӧffler

Quais resultados desse eco podem ser visualizados em detalhes com:

$ echo *ffler | od -vAn -tx1c
  4c  6f  cc  88  66  66  6c  65  72  20  4c  c3  b6  66  66  6c
   L   o 314 210   f   f   l   e   r       L 303 266   f   f   l
  65  72  20  4c  d3  a7  66  66  6c  65  72  0a
   e   r       L 323 247   f   f   l   e   r  \n

O que apenas reflete o fato de que cada um é diferente.

Se eles são atribuídos aos argumentos posicionais do shell:

$ set -- $(echo *ffler)

Podemos comparar cada um deles:

[ "$1" == "$2" ] && echo "Diferent" || echo "Equal"

No entanto, é razoável esperar que o primeiro e o segundo sejam equivalentes.
Mas eles são diferentes em a forma como a "composição" é feita .
O 'L\xC3\xB6ffler' usa o formulário NFC (composto).
O 'Lo\xCC\x88ffler' usa o formulário NFD (de-composto).

Você pode usar o uconv ( do pacote icu-devtools ) para converter esses dois formulários.
Na forma decomposta:

$ echo *ffler | uconv -x any-nfd | od -vAn -tx1c
  4c  6f  cc  88  66  66  6c  65  72  20  4c  6f  cc  88  66  66
   L   o 314 210   f   f   l   e   r       L   o 314 210   f   f
  6c  65  72  20  4c  d0  be  cc  88  66  66  6c  65  72  0a
   l   e   r       L 320 276 314 210   f   f   l   e   r  \n

Em forma pré-composta:

$  echo *ffler | uconv -x any-nfc | od -vAn -tx1c
  4c  c3  b6  66  66  6c  65  72  20  4c  c3  b6  66  66  6c  65
   L 303 266   f   f   l   e   r       L 303 266   f   f   l   e
  72  20  4c  d3  a7  66  66  6c  65  72  0a
   r       L 323 247   f   f   l   e   r  \n

Agora, se definirmos esses valores como parâmetros posicionais e compará-los:

$ set -- $( echo *ffler | uconv -x any-nfc | od -vAn -tx1c )
$ [ "$1" == "$2" ] && echo "Diferent" || echo "Equal"

O caractere cyrylic não é equivalente a nenhuma dessas formas de composição.
Se você precisar convertê-lo, para poder comparar esse nome com os outros, precisará de uma ferramenta que entenda os caracteres de múltiplos bytes.

$ echo *ffler | sed 's/\xd3\xa7/\xc3\xb6/g' | od -vAn -tx1c
  4c  6f  cc  88  66  66  6c  65  72  20  4c  c3  b6  66  66  6c
   L   o 314 210   f   f   l   e   r       L 303 266   f   f   l
  65  72  20  4c  c3  b6  66  66  6c  65  72  0a
   e   r       L 303 266   f   f   l   e   r  \n

E trabalhando apenas no formulário NFC:

$ echo *ffler | uconv -x any-nfc | sed 's/\xd3\xa7/\xc3\xb6/g' | od -vAn -tx1c
  4c  c3  b6  66  66  6c  65  72  20  4c  c3  b6  66  66  6c  65
   L 303 266   f   f   l   e   r       L 303 266   f   f   l   e
  72  20  4c  c3  b6  66  66  6c  65  72  0a
   r       L 303 266   f   f   l   e   r  \n

Agora os três nomes são exatamente iguais.

O item acima está esclarecendo sua preocupação real?
Está mesmo perto?

    
por 11.07.2017 / 00:50