J'ai un gros fichier binaire (plusieurs centaines de Go) et je veux en extraire un segment. Je connais les chaînes hexagonales des points de début et de fin.
Une solution possible (en supposant que vous puissiez faire une copie de fichier) pourrait utiliser l'exemple suivant
tf
et a une longueur de 5000 octets puis
faire une copie de tf
vers un nouveau fichier blah
avec motif de départ changé
$ LC_ALL=C sed 's/'`printf "\x4f\x0f\x87\x82"`'/'`printf "AAAA"`'/' <tf > blah
maintenant trouver l'emplacement où tf
et blah
différer ( note - sed écrit un octet supplémentaire contenant une nouvelle ligne à la fin du fichier modifié. Nous comparons donc jusqu'à la longueur du fichier d'origine. tf
. Le fichier généré blah
devrait être un octet plus long ).
$ cmp -n 5000 -b tf blah
cela donnera un décalage d'octet, bs, où les fichiers diffèrent, par exemple,
tf blah differ: byte 4337, line 10 is 117 O 101 A
maintenant faire la même chose pour le motif de fin
$ LC_ALL=C sed 's/'`printf "\xfb\x8c\xe2\xa0"`'/'`printf "AAAA"`'/' < tf > blah2
$ cmp -n 5000 -b tf blah2
tf blah2 differ: byte 4433, line 10 is 373 ? 101 A
maintenant utiliser dd
extraire une partie de l'intérêt
dd if=tf skip=4336 bs=1 count=100 > fbit
Quelques notes supplémentaires:
certaines versions de sed supportent un -b
option qui traite le fichier d'entrée comme binaire. D'autres versions ont un -z
option qui sépare les lignes par des caractères NUL. Dans les deux cas, les motifs correspondants contenant une nouvelle ligne ou répartis sur une nouvelle ligne n'ont pas été testés.
la count=100
dépendra de la longueur du motif trouvé et de la question de savoir si le motif choisi doit être inclus dans l'extrait (cela n'était pas clair dans la question). La formule générale est compte = (décalage de fin) - (décalage de début) + (taille du motif de fin) . Les pièces pour l'exemple spécifique sont 4433-4337 + 1, ce qui donne 97 octets. Cela va du début du motif de début jusqu'au premier octet du motif de fin inclus. Trois octets supplémentaires sont ensuite ajoutés pour donner 100 dans cet exemple, car le modèle final avait quatre octets et l'exemple comprend le modèle final. Si le motif final n'était pas voulu, alors count=96
serait la valeur.
une approche plus robuste aux nouvelles lignes et l'utilisation de la commande hexdump est possible. Je n'ai pas complètement testé cette approche. Il utilisera essentiellement hexdump avec un peu de sed, grep et tr pour convertir le fichier binaire original en un fichier hexadécimal au format ascii. Ensuite, le même processus pourrait être appliqué, mais avec une arithmétique plus complexe, etc ... La commande hexdump nécessaire serait
hexdump -v -x tf | sed s/'^[0-9]*\(.*\)/\1/' | sed s'/ *//g' | grep '[0-9]' | tr -d '\n' > tf.txt
Après le hexdump
suivre le même processus de sed
et cmp
pourrait être employé. Le modèle à faire correspondre devra être mis à jour pour utiliser des caractères ASCII hexdump et non l'impression hexadécimale brute.
Cette approche devrait également gérer les caractères de nouvelle ligne.
LC_ALL=C
semble être nécessaire sur OSX par défaut. Sans elle la sed
commande donne une erreur RE error: illegal byte sequence
. Cela peut ne pas être vrai sur toutes les plateformes et / ou les distributions de système d'exploitation.
96
? (Indice: réfléchissez-y. Je crois que c'est faux.) (2) Cela ne fonctionnera pas si l'un des octets connus est hexadécimal.0A
. Pouvez-vous étendre votre réponse pour couvrir ce cas? (3) estLC_ALL=C
nécessaire? Pouvez-vous expliquer pourquoi? (4) De même, pouvez-vous expliquer pourquoi-n 5000
est nécessaire? (5) Veuillez rechercher “UUOC”. ………………………………………………………………………………………… S'il vous plaît ne répondez pas dans les commentaires; modifier votre réponse pour la rendre plus claire et plus complète.98
a eu tort (le96
était une faute de frappe). En effet, votre réponse montre un exemple de motif de fin qui est quatre octets. Sinon, bon travail.