J'ai quelques dumps de base de données d'un système Windows sur ma boîte. Ce sont des fichiers texte. J'utilise cygwin pour les remercier. Ceux-ci semblent être des fichiers de texte brut; Je les ouvre avec des éditeurs de texte tels que le bloc-notes et le wordpad. Ils ont l'air lisibles. Cependant, quand je lance grep sur eux, il dira binary file foo.txt matches
.
J'ai remarqué que les fichiers contiennent des NUL
caractères ascii , qui, à mon avis, sont des artefacts du dump de la base de données.
Alors, qu'est-ce qui fait que grep considère ces fichiers comme étant binaires? Le NUL
personnage? Y at-il un drapeau sur le système de fichiers? Que dois-je changer pour que grep me montre les correspondances de lignes?
--null-data
peut être utile siNUL
est le délimiteur.Réponses:
S'il y a un
NUL
caractère n'importe où dans le fichier, grep le considérera comme un fichier binaire.Il pourrait y avoir une solution de rechange comme celle-ci
cat file | tr -d '\000' | yourgrep
pour éliminer tous les éléments null en premier, puis pour effectuer une recherche dans le fichier.la source
-a
/--text
, du moins avec GNU grep.NUL
(probablement parce qu'elle appelle la commande printf de C et lui donne la ligne correspondante?). Sur un tel système, agrep cmd .sh_history
retournera autant de lignes vides qu'il y a de lignes correspondant à 'cmd', car chaque ligne de sh_history a un format spécifique avec unNUL
au début de chaque ligne. (Mais votre commentaire "au moins sur GNU grep" est probablement devenu réalité. Je n'en ai pas sous la main pour le tester, mais je m'attends à ce qu'ils s'en sortent bien.)grep
sur cygwin, était considéré comme binaire parce qu'il avait un long tiret (0x96) au lieu d'un trait d'union ASCII / minus (0x2d) normal. Je suppose que cette réponse a résolu le problème du PO, mais il semble que ce soit incomplet.grep -a
a travaillé pour moi:la source
Vous pouvez utiliser l'
strings
utilitaire pour extraire le contenu du texte de tout fichier, puis l'envoie àgrep
, comme ceci:strings file | grep pattern
.la source
GNU grep 2.24 RTFS
Conclusion: 2 et 2 cas seulement:
NUL
, par exempleprintf 'a\0' | grep 'a'
erreur de codage selon C99
mbrlen()
, par exemple:car
\x80
ne peut pas être le premier octet d'un point Unicode UTF-8 : UTF-8 - Description | en.wikipedia.orgDe plus, comme l'a mentionné Stéphane Chazelas, qu'est-ce qui fait que grep considère un fichier comme étant binaire? | Unix et Linux Stack Exchange , ces vérifications ne sont effectuées que jusqu’à la première lecture de tampon de longueur TODO.
Seulement jusqu'à la première lecture du tampon
Ainsi, si une erreur NUL ou une erreur d'encodage se produit au milieu d'un fichier très volumineux, il se peut qu'il s'agisse d'une erreur.
J'imagine que c'est pour des raisons de performance.
Ex: ceci imprime la ligne:
mais cela ne veut pas:
La taille réelle de la mémoire tampon dépend de la façon dont le fichier est lu. Par exemple comparer:
Avec la
sleep
, la première ligne est transmise à grep même si elle ne dure qu'un octet, car le processus passe en veille, et la deuxième lecture ne vérifie pas si le fichier est binaire.RTFS
Recherchez où le message d'erreur stderr est codé:
Nous amène à
/src/grep.c
:Si ces variables étaient bien nommées, nous en sommes essentiellement à la conclusion.
encoding_error_output
La recherche rapide pour
encoding_error_output
indique que le seul chemin de code pouvant le modifier passe parbuf_has_encoding_errors
:alors juste
man mbrlen
.nlines_first_null et nlines
Initialisé comme:
alors quand un nul est trouvé
0 <= nlines_first_null
devient vrai.TODO quand peut-il
nlines_first_null < nlines
être faux? Je suis paresseux.POSIX
Ne définit pas les options binaires grep - recherche dans un fichier un motif | pubs.opengroup.org , et GNU grep ne le documente pas, RTFS est donc le seul moyen.
la source
(printf '\n\0y') | grep y
avec(printf '\n'; sleep 1; printf '\0y') | grep y
par exemple.export LC_CTYPE='en_US.UTF-8'
exemple dans mon exemple ou quelque chose d'autre? Buf read: exemple étonnant, ajouté pour répondre. Vous avez lu évidemment la source plus que moi, me rappelle ces kôans hacker "L'étudiant était éclairé" :-)Un de mes fichiers texte était soudainement considéré comme binaire par grep:
La solution a été de le convertir en utilisant
iconv
:la source
0xFC
hexadécimal, donc en dehors de la plage attendue par utp8 (jusqu'à0x7F
). Vérifiez avec printf 'a \ x7F' | grep 'a' comme décrit par Ciro ci-dessus.Le fichier
/etc/magic
ou/usr/share/misc/magic
contient une liste de séquences que la commandefile
utilise pour déterminer le type de fichier.Notez que le binaire peut simplement être une solution de secours. Parfois, les fichiers avec un codage étrange sont également considérés comme binaires.
grep
sur Linux a quelques options pour gérer les fichiers binaires comme--binary-files
ou-U / --binary
la source
mbrlen()
. Exemple interprétation et la source à l' adresse: unix.stackexchange.com/a/276028/32558Un de mes étudiants a eu ce problème. Il y a un bug
grep
dansCygwin
. Si le fichier contient des caractères non-ascii,grep
etegrep
voir comme binaire.la source
En réalité, en répondant à la question "Qu'est-ce qui fait que grep considère un fichier comme étant binaire?", Vous pouvez utiliser
iconv
:Dans mon cas, il y avait des caractères espagnols qui apparaissaient correctement dans les éditeurs de texte mais grep les considérait comme binaires;
iconv
la sortie m'a pointé vers les numéros de ligne et de colonne de ces caractèresDans le cas de
NUL
caractères,iconv
les considérera comme normaux et n'imprimera pas ce type de sortie, donc cette méthode ne convient pasla source
J'ai eu le même problème. J'avais l'habitude
vi -b [filename]
de voir les caractères ajoutés. J'ai trouvé les caractères de contrôle^@
et^M
. Puis dans vi tapez:1,$s/^@//g
pour supprimer les^@
caractères. Répétez cette commande pour^M
.Avertissement: pour obtenir les caractères de contrôle "bleus", appuyez sur Ctrl+ vpuis Ctrl+ Mou Ctrl+ @. Puis enregistrez et quittez vi.
la source