Comment grep un fichier texte qui contient des données binaires?

Grep renvoie

Binary file test.log matches

Par exemple

echo    "line1 re x00rnline2rnline3 rern" > test.log  # in zsh
echo -e "line1 re x00rnline2rnline3 rern" > test.log  # in bash
grep re test.log

Je souhaite que le résultat montre line1 et line3 (total deux lignes).

Est-il possible d'utiliser tr Convertir les données non imprimables en données lisibles, pour laisser grep fonctionner à nouveau?

102
demandé sur Daniel YC Lin 2012-04-03 10:47:40

10 réponses

Vous pouvez exécuter le fichier de données via cat -v, par exemple

$ cat -v tmp/test.log | grep re
line1 re ^@^M
line3 re^M

Qui pourrait ensuite être post-traité pour supprimer les pourriels; ceci est plus analogue à votre requête sur l'utilisation de tr pour la tâche.

56
répondu vielmetti 2015-07-18 05:36:16

Une façon est de simplement traiter les fichiers binaires comme du texte de toute façon, avec grep --text mais cela peut bien entraîner l'envoi d'informations binaires à votre terminal. Ce n'est pas vraiment une bonne idée si vous utilisez un terminal qui interprète le flux de sortie (comme VT/DEC ou bien d'autres).

Vous pouvez également envoyer votre fichier via tr avec la commande suivante:

tr '[\000-\011\013-\037\177-\377]' '.' <test.log | grep whatever

Cela changera tout ce qui est inférieur à un caractère d'espace (sauf newline) et tout ce qui est supérieur à 126, en un . caractère, ne laissant que les printables.


Si vous voulez que chaque caractère" illégal " soit remplacé par un caractère différent, vous pouvez utiliser quelque chose comme le programme C suivant, un filtre d'entrée standard classique:

#include<stdio.h>
int main (void) {
    int ch;
    while ((ch = getchar()) != EOF) {
        if ((ch == '\n') || ((ch >= ' ') && (ch <= '~'))) {
            putchar (ch);
        } else {
            printf ("{{%02x}}", ch);
        }
    }
    return 0;
}

Cela vous donnera {{NN}}, où NN est le code hexadécimal du caractère. Vous pouvez simplement ajuster le printf pour le style de sortie que vous voulez.

Vous pouvez voir ce programme en action ici, où il:

pax$ printf 'Hello,\tBob\nGoodbye, Bob\n' | ./filterProg
Hello,{{09}}Bob
Goodbye, Bob
82
répondu paxdiablo 2015-02-05 02:50:28
grep -a

Ça ne peut pas être plus simple que ça.

78
répondu James Selvakumar 2014-01-21 05:44:00

Vous pouvez utiliser" strings " pour extraire des chaînes d'un fichier binaire, par exemple

strings binary.file | grep foo
32
répondu moodywoody 2012-04-03 06:50:53

Vous pouvez forcer grep à regarder les fichiers binaires avec:

grep --binary-files=text

Vous pouvez également ajouter -o (--only-matching) donc, vous n'obtenez pas des tonnes de charabia binaire qui va bork votre terminal.

19
répondu A B 2012-04-03 06:56:02

À partir de Grep 2.21, les fichiers binaires sont traités différemment :

Lors de la recherche de données binaires, grep peut maintenant traiter les octets non textuels comme ligne terminateur. Cela peut augmenter considérablement les performances.

Donc, ce qui se passe maintenant, c'est qu'avec les données binaires, tous les octets non textuels (y compris les nouvelles lignes) sont traités comme des terminaisons de ligne. Si vous voulez changer cela comportement, vous pouvez:

  • Utiliser --text. Cela garantira que seules les nouvelles lignes sont en ligne les terminateurs

  • Utiliser --null-data. Cela garantira que seuls les octets nuls sont des terminateurs de ligne

14
répondu Steven Penny 2015-07-18 00:20:29

Comme James Selvakumar l'a déjà dit, grep -a fait l'affaire. -A ou -- text force Grep à gérer le flux d'entrée en tant que texte. Voir la page de manuel http://unixhelp.ed.ac.uk/CGI/man-cgi?grep

Essayez

cat test.log | grep -a somestring
3
répondu DerKnorr 2014-12-11 08:48:17

Vous pouvez faire

strings test.log | grep -i

Cela convertira la sortie give sous forme de chaîne lisible en grep.

2
répondu Mrid 2013-05-13 20:35:15

Grep-a forcera grep à rechercher et à sortir à partir d'un fichier que grep pense binaire. grep-un nouveau test.log

1
répondu Kevin Buchs 2017-02-16 20:27:12

Vous pouvez également essayer l'Outil Word Extractor . Word Extractor peut être utilisé avec n'importe quel fichier de votre ordinateur pour séparer les chaînes contenant du texte / des mots humains du code binaire (applications exe, DLL).

0
répondu MattCollW 2013-05-31 05:32:02