Comment grep décide-t-il qu'un fichier est binaire?


8

J'ai un grand fichier texte utf-8 avec lequel je recherche fréquemment grep. Récemment, j'ai grepcommencé à signaler qu'il s'agissait d'un fichier binaire. Je peux continuer à le rechercher avec grep -a, mais je me demandais avec quel changement il a décidé que le fichier était maintenant binaire.

J'ai une copie du mois dernier où le fichier n'est plus détecté comme binaire, mais ce n'est pas pratique pour diffeux car ils diffèrent sur> 20 000 lignes.

file identifie mon fichier comme

Texte anglais UTF-8 Unicode, avec de très longues lignes

Comment trouver les caractères / lignes / etc. dans mon fichier qui déclenchent ce changement?


La question similaire, non dupliquée 19907 couvre la possibilité de NUL mais grep -Pc '[\x00-\x1F]'dit que je n'ai pas de NUL ou d'autres chaarcteurs de contrôle ANSI.


J'essaierais ceci dans cet ordre: 1. Exécutez-le avec strace / ltrace pour vérifier quelle entrée provoque ce message «binaire» 2. Consultez la source de grep et lisez-le
ott--

@muru: J'utilise gnu grep, mais si vous avez la réponse pour une autre version, je serais également intéressé.
Charles

Impair. J'ai un fichier qui, je le sais, contient un nulet quelques Escs. J'ai essayé de les saluer. J'ai pu trouver le escs ( \x1B), mais le nulne s'est jamais présenté. Le test donné ci-dessus a montré 1, pour la ligne contenant Escs, mais rien pour une plage qui n'en contenait pas \x1B. Je ne ferais pas confiance à ce test. Essayez à la grep -zc .place (devrait être un de plus que le nombre de nuls dans votre fichier). (En outre, il vaut peut-être mieux utiliser [[:cntrl:]].)
muru

Essayez également: sed -z 's/.*\(....\)$/\1/' foo | od -cde voir quelques caractères avant NUL(s'il y en a un), ce qui pourrait vous conduire au problème.
muru

@muru: Mon sedn'a pas l' -zoption: sed: invalid option -- 'z'.
Charles

Réponses:


2

Cela semble être la présence du caractère nul dans le fichier. (Affiché ^ @ généralement) J'ai entré divers caractères de contrôle dans un fichier texte (comme supprimer, ^ ?, par exemple), et seul le caractère nul a amené grep à le considérer un binaire. Cela n'a été testé que pour grep. Les commandes less et diff, par exemple, peuvent avoir des méthodes différentes. Les caractères de contrôle n'apparaissent en général que dans les binaires. Les exceptions sont les caractères d'espacement: saut de ligne (^ M), tabulation (^ I), saut de page (^ L), tabulation verticale (^ K) et retour (^ J).

Cependant, les caractères étrangers, comme les lettres arabes ou chinoises, ne sont pas des ascii standard et peuvent peut-être être confondus avec des caractères de contrôle. C'est peut-être pour cela que ce n'est que le caractère nul.

Vous pouvez le tester par vous-même en insérant des caractères de contrôle dans un fichier texte à l'aide de l'éditeur de texte vim. Passez simplement en mode insertion, appuyez sur control-v, puis sur le caractère de contrôle.


2

Une implémentation grep moderne typique ne devrait déclarer un fichier "binaire" que s'il y a des octets nuls à l'intérieur. Tout le reste devrait être OK.

Je ne peux pas parler de l'implémentation grep que vous utilisez ...


1

Une erreur de codage selon mbrlen () oblige également GNU grep 2.24 à le considérer comme binaire

Par exemple:

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

car \x80ne peut pas être le premier octet d'un point Unicode UTF-8: https://en.wikipedia.org/wiki/UTF-8#Description

C'est d'ailleurs la seule autre possibilité NUL.

grepInterprétation du code source GNU qui mène à cette conclusion: Qu'est - ce qui fait que grep considère un fichier comme binaire?

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.