É possível usar o split para fazer pedaços de caracteres de bytes unicode chineses?

4

Por um tempo, tenho lidado com texto unicode chinês. Claro, as regras usuais se aplicam. Eu posso grep para caracteres da mesma maneira que eu faria para as palavras. Isso é muito útil para mim.

Mas há uma coisa que ainda não descobri. E eu não sei se é possível.

É lógico que o CJK não seria receptivo a todos os tipos de divisão. Mas a divisão de linha funciona, é claro, usando split -l .

O que eu quero fazer é conseguir split de um número arbitrário de caracteres.

Meu entendimento do unicode chinês é que cada glifo tem o mesmo número de bytes de tamanho. Como tal, deve haver algum número mágico de bytes, um mínimo múltiplo comum, o que me permitiria usar split -b , certo?

Eu usei tentativa e erro uma vez, esperando chegar a esse número, mas não consegui fazê-lo. Em vez disso, os caracteres em si foram divididos, de modo que dividir um arquivo CJK em dois.

Por exemplo, dado um arquivo chamado 'dunting' que contém apenas a string 洞庭湖, usar split acaba gerando o que é essencialmente absurdo. Um dos personagens se torna 溭 durante o split ...

    
por ixtmixilix 06.02.2012 / 18:53

3 respostas

3

Cada caractere tem três bytes de largura, conforme mostrado neste xxd output:

$ xxd chinese-bytes
0000000: e6b4 9ee5 baad e6b9 96                   .........

split -b3 funciona para mim.

$ split -b3 chinese-bytes
$ echo xa?
xaa xab xac
$ cat xaa; echo
洞
$ cat xab; echo
庭
$ cat xac; echo
湖
    
por 06.02.2012 / 19:28
2

Até onde eu sei, todos os caracteres chineses têm 3 bytes de comprimento quando codificados em UTF-8 , o codificação Unicode normal no unix. Mas os caracteres não-chineses, como espaços e novas linhas, podem ter uma largura diferente (os caracteres básicos de controle, bem como os formulários com dígitos arábicos e outros, têm um único byte). O utilitário split só entende números fixos de bytes, por isso vai cortar indiscriminadamente fora de alinhamento.

Você precisará usar uma ferramenta mais sofisticada para dividir cada 42 caracteres. Aqui está um trecho de Perl que deve fazer o truque (não testado). Note que trata cada caractere igualmente: um caractere chinês conta para 1, assim como uma nova linha.

perl -CDS -e '
    $n = 0;
    while (read STDIN, $buf, 42) {
        open OUT, sprintf("> output-$n.txt") or die;
        print OUT $buf;
        close OUT or die;
        ++$n;
    }'
    
por 07.02.2012 / 01:34
-1

No terminal mac estou usando egrep -o '.'

    
por 16.10.2013 / 14:59