Existe uma maneira de grep uma pasta e mostrar todas as linhas contendo caracteres não ascii?

3

Algum código com o qual estou trabalhando tem vários comentários escritos em japonês e estou trabalhando para traduzi-los para o inglês. Existe alguma maneira de "grep" para todas as linhas que contenham caracteres japoneses ou pelo menos qualquer caractere não ascii?

    
por hugomg 01.04.2015 / 01:39

4 respostas

2

Grepping para caracteres não-ASCII é fácil: defina uma localidade onde apenas caracteres ASCII sejam válidos, procure por caracteres inválidos.

LC_CTYPE=C grep '[^[:print:]]' myfile

Se você quiser procurar por caracteres japoneses, é um pouco mais complicado. Com o grep, você precisará garantir que sua configuração LC_CTYPE locale corresponda à codificação dos arquivos. Você também precisará garantir que sua configuração LC_COLLATE esteja configurada para japonês se você quiser usar uma expressão de intervalo de caracteres. Por exemplo, no Linux (determinei o primeiro e último caractere que é considerado japonês, observando a LC_COLLATE section /usr/share/i18n/locales/ja_JP ):

LC_CTYPE=ja_JP.UTF-8 LC_COLLATE=ja_JP.UTF-8 egrep '[。-龥]' myfile

ou se você quiser manter o ASCII no seu script

LC_CTYPE=ja_JP.UTF-8 LC_COLLATE=ja_JP.UTF-8 egrep $'[\uff61-\u9fa5]' myfile

Isso inclui alguns caracteres de pontuação que também são usados em inglês, como e × .

O Perl possui recursos internos para classificar caracteres. Você pode usar a classe de caracteres \p para corresponder caracteres baseados em Propriedades do Unicode . Passe o comutador da linha de comando -CSD para informar ao Perl que tudo está em Unicode com a codificação UTF-8.

perl -CSD -ne 'print if /\p{Hiragana}|\p{Katakana}/' myfile

Se seus arquivos não estiverem codificados em UTF-8, você precisará ligar para binmode explicitamente para informar Perl sobre sua codificação. Isso é um uso muito avançado de perllocale para mim. Alternativamente, você pode primeiro recodificar a linha em UTF-8 .

Como alternativa, em Perl, você pode usar intervalos de caracteres numéricos. Por exemplo, para procurar caracteres nos blocos Hiragana e Katakana Unicode:

perl -CSD -ne 'print if /[\x{3040}-\x{30ff}]/' a
    
por 02.04.2015 / 01:39
1

Tente isto:

grep '[^[:print:][:space:]]'

(Dependendo da sua configuração local, talvez você precise prefixar por LANG=C .)

    
por 01.04.2015 / 01:56
1

Se você não se importar em usar o perl, ele terá suporte a Unicode mais extenso na forma de classes como {Katakana} e {Hiragana} , que não acredito que estejam atualmente disponíveis mesmo nas versões do grep que fornecem algum suporte PCRE. No entanto, parece exigir uma descodificação explícita de UTF-8, por exemplo,

perl -MEncode -ne 'print if decode("UTF-8",$_) =~ /\p{Hiragana}/' somefile

Para percorrer diretórios como grep -R, você pode usar o comando find , algo como

find -type f -exec perl -MEncode -ne 'print if decode("UTF-8",$_) =~ /\p{Hiragana}/' {} \;

ou para imitar o formato de saída rotulado de filename:match do grep recursivo,

find -type f -exec perl -MEncode -lne 'printf "%s:%s\n",$ARGV,$_ if decode("UTF-8",$_) =~ /\p{Hiragana}/' {} \;
    
por 01.04.2015 / 04:52
0

Meus arquivos foram codificados em iso-8859-1, então qualquer coisa que tentasse ler a entrada em minha localidade padrão (utf-8) não reconheceria os caracteres japoneses. No final, consegui resolver meu problema com o seguinte comando:

env LC_CTYPE=iso-8859-1  grep -nP '[\x80-\xff]' ./*

-P é permitir a sintaxe Perllike para intervalos de caracteres.
-n é para imprimir os números de linha ao lado dos nomes das linhas

\x80 to \xff são os caracteres "não ascii"

Alterar a variável de ambiente LC_CTYPE para iso-8859-1 faz com que o grep leia meus campos byte por byte e me permite detectar quaisquer bytes "ascii estendidos" como possíveis caracteres japoneses. Se eu usar a codificação de sistema padrão do UTF-8, o grep sai com um erro "seqüência de bytes UTF-8 inválida na entrada".

    
por 01.04.2015 / 05:14

Tags