89 votes

Comment extraire un seul morceau d'octets d'un fichier ?

Sur un ordinateur de bureau Linux (RHEL4), je souhaite extraire une série d'octets (généralement moins de 1 000) d'un fichier volumineux (> 1 gigaoctet). Je connais le décalage dans le fichier et la taille du morceau.

Je peux écrire du code pour faire cela mais existe-t-il une solution en ligne de commande ?

Idéalement, quelque chose comme :

magicprogram --offset 102567 --size 253 < input.binary > output.binary

134voto

Thomas Padron-McCarthy Points 13131

Essayez dd :

dd skip=102567 count=253 if=input.binary of=output.binary bs=1

L'option bs=1 définit la taille du bloc, ce qui rend dd lire et écrire un octet à la fois. La taille par défaut des blocs est de 512 octets.

La valeur de bs affecte également le comportement de skip y count puisque les nombres dans skip y count sont les nombre de blocs que dd sautent et lisent/écrivent, respectivement.

76voto

ChronoTrigger Points 2788

C'est une vieille question, mais j'aimerais ajouter une autre version de la dd qui est mieux adaptée aux gros morceaux d'octets :

dd if=input.binary of=output.binary skip=$offset count=$bytes iflag=skip_bytes,count_bytes

$offset y $bytes sont des nombres en unités d'octets.

La différence avec la réponse acceptée par Thomas est que bs=1 n'apparaît pas ici. bs=1 fixe la taille des blocs d'entrée et de sortie à 1 octet, ce qui le rend terriblement lent lorsque le nombre d'octets à extraire est important.

Cela signifie que nous laissons la taille du bloc ( bs ) à sa valeur par défaut de 512 octets. Utilisation de iflag=skip_bytes,count_bytes nous disons dd pour traiter les valeurs après skip y count en tant que quantité d'octets au lieu de quantité de blocs.

13voto

Ciro Santilli Points 3341

head -c + tail -c

Je ne sais pas comment il se compare à dd en efficacité, mais c'est amusant :

printf "123456789" | tail -c+2 | head -c3

sélectionne 3 octets, en commençant par le 2ème :

234

Voir aussi :

2voto

Albert Burbea Points 41

Encore plus rapide

dd bs=<req len> count=1 skip=<req offset> if=input.binary of=output.binary

3 votes

Le problème ici est que skip est en unités de bs .

0 votes

C'est un détail pour l'exécuteur, et toujours mieux que le ci-dessus, vrai que vous auriez besoin de recalculer comme : req_offset=$(bc <<< "$offset/$bs") et s'assurer qu'il s'agit d'une valeur ronde.

1voto

Joe Points 17829

La commande dd peut faire tout cela. Regardez les paramètres seek et/ou skip qui font partie de l'appel.

0 votes

Mais dd peut être très lent lorsque vous voulez un accès mal aligné. et faire bs=1 est super lent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X