Como fazer uma pesquisa em regex em um arquivo UTF-16LE em um locale UTF-8?

2

EDIT: Devido a um comentário Warren Young feito, me fez perceber que eu não estava claro em um ponto bastante relevante. Minha string de pesquisa já está na ordem UTF-16LE (não na ordem Unicode Codepoint, que é UTF-16BE), então talvez o problema Unicode seja um tanto irrelevante,

Talvez meu problema seja uma questão de como eu faço grep para bytes (não chars) em grupos de 2 bytes , isto é. para que UTF-16LE \x09\x0A não seja tratado como TAB, newline, mas apenas como 2 bytes que são UTF-16LE ? ... Nota: Eu não preciso me preocupar com pares substitutos UTF-16, então blocos de 2 bytes estão bem.

Aqui está um exemplo de amostra para esta string de 3 caracteres ऊपर :

  • \x09\x0A\x09\x2A\x09\x30

    mas não retorna nada, embora a string esteja no arquivo.

(aqui é o post original)
Ao pesquisar um arquivo UTF-16LE com um padrão no formato \x00\x01\x...etc , encontrei problemas para alguns valores. Eu tenho usado sed (e experimentado com grep ), mas estando na localidade UTF-8 eles reconhecem alguns valores UTF-16LE como caracteres ASCII. Estou bloqueado para usar UTF-16, portanto, a recodificação para UTF-8 não é uma opção.

por exemplo. Neste texto (UNICODE 090A), embora seja um único caractere, é percebido como dois caracteres ASCII \x09 e \x0A .

grep tem uma opção -P (perl) que pode procurar por \x00\x... patterns, mas estou recebendo a mesma interpretação ASCII.

Existe alguma maneira de usar grep -P para pesquisar em um modo UTF-16, ou talvez melhor, como isso pode ser feito em perl ou algum outro script.

grep parece ser o mais atraente por causa de seu tamanho compacto, mas qualquer que seja o trabalho feito, isso irá ultrapassar essa preferência.

PS; Meu exemplo usa uma string literal, mas meu uso real precisa de uma pesquisa de estilo regex. Então este exemplo de perl não é bem o que eu estou procurando, embora ele processe o arquivo como UTF-16. .. Eu prefiro não ter que abrir e fechar o arquivo ... Eu acho que perl tem formas mais compactas para coisas básicas como uma pesquisa regex. Eu estou atrás de algo com esse tipo de sintaxe compacta.

    
por Peter.O 09.06.2012 / 12:44

2 respostas

8

Minha resposta é essencialmente a mesma que em sua outra pergunta sobre esse assunto :

$ iconv -f UTF-16LE -t UTF-8 myfile.txt | grep pattern

Como na outra pergunta, talvez você precise de conversão de término de linha também, mas o ponto é que você deve converter o arquivo para a codificação local para poder usar ferramentas nativas diretamente.

    
por 09.06.2012 / 15:12
1

Eu acredito que a resposta de Warren é uma solução melhor geral * nix, mas este script perl funciona exatamente como eu queria (para minha situação um pouco fora do padrão). Isso exige que eu mude um pouco o formato atual do padrão de pesquisa:
de \x09\x0A\x09\x2A\x09\x30\x00\s09
para \x{090A}\x{092A}\x{0930}\x{0009}

Faz tudo em um processo que é particularmente o que eu procurava.

#! /usr/bin/env perl
use strict;
use warnings;
die "3 args are required" if scalar @ARGV != 3;
my $if =$ARGV[0];
my $of =$ARGV[1];
my $pat=$ARGV[2];
open(my $ifh, '<:encoding(UTF-16LE)', $if) or warn "Can't open $if: $!";
open(my $ofh, '>:encoding(UTF-16LE)', $of) or warn "Can't open $of: $!";
while (<$ifh>) { print $ofh $_ if /^$pat/; }
    
por 10.06.2012 / 01:19