Como o grep decide que um arquivo é binário?


8

Eu tenho um grande arquivo de texto utf-8 com o qual pesquiso frequentemente grep. Recentemente, grepcomeçou a relatar que era um arquivo binário. Posso continuar pesquisando grep -a, mas fiquei imaginando com que alteração decidi que o arquivo agora era binário.

Eu tenho uma cópia do mês passado em que o arquivo não é mais detectado como binário, mas não é prático para diffeles, pois eles diferem em> 20.000 linhas.

file identifica meu arquivo como

Texto em UTF-8 Unicode em inglês, com linhas muito longas

Como posso encontrar os caracteres / linhas / etc. no meu arquivo que está acionando essa alteração?


A pergunta similar, não duplicada, 19907, cobre a possibilidade de NUL, mas grep -Pc '[\x00-\x1F]'diz que eu não tenho NUL ou quaisquer outros chaarcters de controle ANSI.


Eu tentaria isso nesta ordem: 1. Execute-o com strace / ltrace para verificar quais entradas causam essa mensagem 'binária' 2. Verifique a fonte do grep e leia-a
ott--

@ muru: Estou usando o gnu grep, mas se você tiver a resposta para outra versão, eu também estaria interessado.
Charles

Ímpar. Eu tenho um arquivo que eu sei que contém um nule alguns Escs. Eu tentei grepping para eles. Eu consegui encontrar o escs ( \x1B), mas o nulnunca apareceu. O teste acima mostrou 1, para a linha que contém Escs, mas nada para qualquer faixa que não contenha \x1B. Eu não confiaria nesse teste. Tente em grep -zc .vez disso (deve ser um a mais que o número de nuls no seu arquivo). (Além disso, você pode ser melhor fora de usar [[:cntrl:]].)
Muru

Tente também: sed -z 's/.*\(....\)$/\1/' foo | od -cver alguns caracteres antes do NUL(se houver), o que pode levar você ao problema.
muru 17/09/2015

@muru: My sednão tem uma -zopção: sed: invalid option -- 'z'.
Charles

Respostas:


2

Parece ser a presença do caractere nulo no arquivo. (Exibido ^ @ normalmente) Digitei vários caracteres de controle em um arquivo de texto (como excluir, ^ ?, por exemplo), e apenas o caractere nulo fez com que o grep o considerasse um binário. Isso foi testado apenas para grep. Os comandos less e diff, por exemplo, podem ter métodos diferentes. Os caracteres de controle em geral não aparecem, exceto nos binários. As exceções são os caracteres de espaço em branco: nova linha (^ M), guia (^ I), avanço de página (^ L), guia vertical (^ K) e retorno (^ J).

No entanto, caracteres estrangeiros, como letras árabes ou chinesas, não são ascii padrão e talvez possam ser confundidos com caracteres de controle. Talvez seja por isso que é apenas o caractere nulo.

Você pode testá-lo inserindo caracteres de controle em um arquivo de texto usando o editor de texto vim. Vá para o modo de inserção, pressione control-v e, em seguida, o caractere de controle.


2

Uma implementação típica do grep moderno só deve declarar um arquivo "binário" se houver nul bytes dentro. Qualquer outra coisa deve ficar bem.

Não posso falar pela implementação grep que você usa ...


1

Um erro de codificação de acordo com mbrlen () também faz com que o GNU grep 2.24 o considere binário

Por exemplo:

export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'

porque \x80não pode ser o primeiro byte de um ponto Unicode UTF-8: https://en.wikipedia.org/wiki/UTF-8#Description

Essa é a única outra possibilidade além disso NUL.

grepInterpretação do código fonte GNU que leva a esta conclusão: O que faz o grep considerar um arquivo como binário?

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.