web-dev-qa-db-fra.com

"grep" offset de la chaîne ascii du fichier binaire

Je génère des fichiers de données binaires qui sont simplement une série d'enregistrements concaténés ensemble. Chaque enregistrement consiste en un en-tête (binaire) suivi de données binaires. L'en-tête binaire contient une chaîne ASCII de 80 caractères. Quelque part au cours de mon cheminement, mon processus d’écriture des fichiers s’est un peu égaré et j’essaie de résoudre ce problème en inspectant la durée de chaque enregistrement.

Cela semble extrêmement lié, mais je ne comprends pas Perl, je n'ai donc pas été en mesure d'obtenir la réponse acceptée. L’autre réponse indique bgrep que j’ai compilé, mais elle veut que je lui donne une chaîne hexadécimale et j’ai plutôt un outil où je peux lui donner la chaîne ascii et qui la trouvera dans les données binaires la chaîne et le décalage d'octet où il a été trouvé.

En d'autres termes, je cherche un outil qui agit comme ceci:

tool foobar filename

ou

tool foobar < filename

et sa sortie ressemble à ceci:

foobar:10
foobar:410
foobar:810
foobar:1210
...

par exemple. la chaîne qui correspond et un décalage d'octet dans le fichier où la correspondance a commencé. Dans cet exemple, je peux en déduire que chaque enregistrement a une longueur de 400 octets.

Autres contraintes:

  • la capacité de rechercher par regex est cool, mais je n'en ai pas besoin pour ce problème
  • Mes fichiers binaires sont volumineux (3,5 Go). Par conséquent, si possible, j'aimerais éviter de lire le fichier en entier.
23
mgilson

Vous pouvez utiliser strings pour ceci:

strings -a -t x filename | grep foobar

Testé avec GNU binutils.

Par exemple, où /bin/ls se trouve --help:

strings -a -t x /bin/ls | grep -- --help

Sortie:

14938 Try `%s --help' for more information.
162f0       --help     display this help and exit
26
Thor
grep --byte-offset --only-matching --text foobar filename

L'option --byte-offset imprime le décalage de chaque ligne correspondante.

L'option --only-matching permet d'imprimer un décalage pour chaque instance correspondante au lieu de chaque ligne correspondante.

L'option --text fait en sorte que grep traite le fichier binaire en tant que fichier texte.

Vous pouvez le raccourcir à:

grep -oba foobar filename

Cela fonctionne dans la version GNU de grep, qui est livré avec Linux par défaut. Cela ne fonctionnera pas dans BSD grep (fourni avec Mac par défaut).

27
Hari Menon

Je voulais faire la même tâche. Bien cordes | grep a fonctionné, j’ai trouvé que gsar était l’outil même dont j'avais besoin.

http://tjaberg.com/

La sortie ressemble à:

>gsar.exe -bic -sfoobar filename.bin
filename.bin: 0x34b5: AAA foobar BBB
filename.bin: 0x56a0: foobar DDD
filename.bin: 2 matches found
0
caesun