Binaire grep sur Linux?

Dire que j'ai généré les suivantes fichier binaire:

# generate file:
python -c 'import sys;[sys.stdout.write(chr(i)) for i in (0,0,0,0,2,4,6,8,0,1,3,0,5,20)]' > mydata.bin

# get file size in bytes
stat -c '%s' mydata.bin

# 14

Et de dire, je veux trouver les emplacements de tous les zéros (0x00), à l'aide d'un grep-syntaxe.

 

Le mieux que je puisse faire pour l'instant est:

$ hexdump -v -e "1/1 \" %02x\n\"" mydata.bin | grep -n '00'

1: 00
2: 00
3: 00
4: 00
9: 00
12: 00

Cependant, cette convertit implicitement chaque octet dans l'original fichier binaire dans un multi-octets ASCII de la représentation, sur lequel grep fonctionne; pas exactement le premier exemple d'optimisation 🙂

Est là quelque chose comme un binaire grep pour Linux? Peut-être, aussi, quelque chose qui serait en faveur d'une expression régulière comme la syntaxe, mais aussi pour les octets de "personnages" qui est, je pourrais écrire quelque chose comme " a(\x00*)b " et de match, de zéro ou plus occurrences de l'octet 0 entre les octets 'a' (97) et " b " (98)?

EDIT: Le contexte, c'est que je suis en train de travailler sur un pilote, où j'ai fait une capture de données de 8 bits; quelque chose se passe mal dans les données, qui peut être kilo-octets jusqu'à mégaoctets, et je tiens à le consulter pour particulier signatures et où ils se produisent. (jusqu'à présent, je travaille avec des extraits de kilo-octets, de sorte que l'optimisation n'est pas important, mais si je commence à être quelques erreurs dans le mégaoctet de capture, et j'ai besoin d'analyser ces, je suppose que je voudrais quelque chose de plus optimisé 🙂 . Et surtout, je voudrais quelque chose où je peux "grep" pour un octet comme un personnage - hexdump m'oblige à rechercher des chaînes par octet)

EDIT2: même question, les différents forum 🙂 grepping par le biais d'un fichier binaire pour une séquence d'octets

EDIT3: Merci pour la réponse par @tchrist, voici aussi un exemple avec "grepping" et de correspondance, et l'affichage des résultats (bien que pas tout à fait la même question que l'OP):

$ perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(.....
$ perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca000000cb000000cc000000cd000000ce     # Matched data (hex)
66357                                  # Offset (dec)
$ perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca000000cb000000cc000000cd000000ce     # Matched data (hex)
66357                                  # Offset (dec)
$ perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca000000cb000000cc000000cd000000ce     # Matched data (hex)
66357                                  # Offset (dec)
\xCC
$ perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca000000cb000000cc000000cd000000ce     # Matched data (hex)
66357                                  # Offset (dec)
$ perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca000000cb000000cc000000cd000000ce     # Matched data (hex)
66357                                  # Offset (dec)
$ perl -ln0777e 'print unpack("H*",$1), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca000000cb000000cc000000cd000000ce     # Matched data (hex)
66357                                  # Offset (dec)
.....)/g' /path/to/myfile.bin ca000000cb000000cc000000cd000000ce # Matched data (hex) 66357 # Offset (dec)

D'avoir les données appariées être regroupés sur un seul octet (deux caractères hexadécimaux), puis "H2 H2 H2 ..." doit être spécifié pour que le nombre d'octets sont là, dans la chaîne correspondante; comme mon match " .....\0\0\0\xCC\0\0\0..... "couvre 17 octets, je peux écrire" "H2"x17 ' en Perl. Chacun de ces "H2" sera de retour d'une variable distincte (comme dans une liste), donc join doit également être utilisés pour ajouter des espaces entre eux - par la suite:

$ perl -ln0777e 'print join(" ", unpack("H2 "x17,$1)), "\n", pos() while /(.....
$ perl -ln0777e 'print join(" ", unpack("H2 "x17,$1)), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca 00 00 00 cb 00 00 00 cc 00 00 00 cd 00 00 00 ce
66357
$ perl -ln0777e 'print join(" ", unpack("H2 "x17,$1)), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca 00 00 00 cb 00 00 00 cc 00 00 00 cd 00 00 00 ce
66357
$ perl -ln0777e 'print join(" ", unpack("H2 "x17,$1)), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca 00 00 00 cb 00 00 00 cc 00 00 00 cd 00 00 00 ce
66357
\xCC
$ perl -ln0777e 'print join(" ", unpack("H2 "x17,$1)), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca 00 00 00 cb 00 00 00 cc 00 00 00 cd 00 00 00 ce
66357
$ perl -ln0777e 'print join(" ", unpack("H2 "x17,$1)), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca 00 00 00 cb 00 00 00 cc 00 00 00 cd 00 00 00 ce
66357
$ perl -ln0777e 'print join(" ", unpack("H2 "x17,$1)), "\n", pos() while /(.....\0\0\0\xCC\0\0\0.....)/g' /path/to/myfile.bin
ca 00 00 00 cb 00 00 00 cc 00 00 00 cd 00 00 00 ce
66357
.....)/g' /path/to/myfile.bin ca 00 00 00 cb 00 00 00 cc 00 00 00 cd 00 00 00 ce 66357

Bien.. c'est vrai que Perl est très agréable "binaire grepping' installation, je dois l'avouer 🙂 tant Que l'on apprend la syntaxe correctement 🙂

  • Pourquoi se soucier de l'optimisation? Cette question est peut-être plus facile de répondre si vous pouvez préciser un peu plus de contexte sur ce que vous essayez de faire.
  • Dean: merci d'avoir soulevé la question! J'ai ajouté un edit, j'espère qu'elle clarifie! @tchrist - merci pour ça, n'avait aucune idée que je pouvais utiliser Perl pour elle 🙂 j'ai à peine trouvé la syntaxe persuader Python pour générer au niveau des octets des fichiers 🙂 (et je l'ai utilisé ici, tout simplement parce que je voulais montrer l'exact contenu du fichier, et le comportement, je suis à la recherche d')
  • J'ai mis à jour ma réponse pour vous. Il devrait être plus facile à comprendre maintenant.
  • Vous pouvez adapter ma technique en Perl pour la recherche de séquences d'octets, trop. perl -ln0777e 'print pos() while /illegal/g' /usr/bin/awk vais vous dire tous les décalages de la chaîne illegal. Remplacer avec /\x1A\0\x43\x41/ juste pour ces quatre octets. Etc. Vous avez déjà ont binaire grepper!
  • merci pour la mise à jour - un binaire grepper en effet 🙂 Certainement une bonne motivation pour moi pour en savoir plus Perl.. Cheers!
  • Essayé le one-liners sur un 250 GO de fichiers et perl dit "de mémoire!". Peut Perl également être utilisé pour les fichiers qui ne tiennent pas en mémoire?

InformationsquelleAutor sdaau | 2010-11-14