J'essaie de copier un bloc d'un fichier binaire dans un nouveau fichier. J'ai le décalage des octets et la longueur du morceau que je veux saisir.
J'ai essayé d'utiliser l'utilitaire Je suppose que je pouvais écrire un petit Perl / python / quel que soit le script à ouvrir Le fichier, cherche au décalage, puis lisez et écrivez la quantité requise de données dans des morceaux. p> existe-t-il un utilitaire qui prend en charge quelque chose comme ça? p> p> dd code>, mais cela semble lire et jeter les données jusqu'au décalage, plutôt que juste Chercher (je suppose parce que DD est destiné à copier / convertir des blocs de données). Cela le rend assez lent (et plus lent le décalage supérieur. C'est la commande que j'ai essayée: p>
6 Réponses :
Vous pouvez utiliser l'option
--input-position=POS
Vous pouvez utiliser queue -c + n code> pour couper les n octets de tête de l'entrée, vous pouvez utiliser tête -cm code> pour produire uniquement les premiers m octets de son INPUT. tail -c+$offset inputfile | head -c$datalength > outputfile
Merci pour les autres réponses. Malheureusement, je ne suis pas en mesure d'installer des logiciels supplémentaires. L'option DDRESCUE est donc sortie. La solution de tête / queue est intéressante (je ne me suis pas réalisée que vous pourriez fournir + à la queue), mais la numérisation à travers les données le rend assez lent.
J'ai fini par écrire un petit script Python pour faire ce que je voulais. La taille de la mémoire tampon doit probablement être à l'écoute d'être identique à celle du réglage de la mémoire tampon externe, mais en utilisant la valeur ci-dessous suffisamment performante sur mon système. P>
#!/usr/local/bin/python
import sys
BUFFER_SIZE = 100000
# Read args
if len(sys.argv) < 4:
print >> sys.stderr, "Usage: %s input_file start_pos length" % (sys.argv[0],)
sys.exit(1)
input_filename = sys.argv[1]
start_pos = int(sys.argv[2])
length = int(sys.argv[3])
# Open file and seek to start pos
input = open(sys.argv[1])
input.seek(start_pos)
# Read and write data in chunks
while length > 0:
# Read data
buffer = input.read(min(BUFFER_SIZE, length))
amount_read = len(buffer)
# Check for EOF
if not amount_read:
print >> sys.stderr, "Reached EOF, exiting..."
sys.exit(1)
# Write data
sys.stdout.write(buffer)
length -= amount_read
La taille de la mémoire tampon doit être suffisamment grande pour maintenir le nombre de syscalls (et de commutateurs de contexte) vers le bas et un multiple de la taille de la page pour rendre la mise en cache aussi heureuse que possible. Le noyau Readahead signifie qu'il n'aura probablement pas d'effet réel sur la taille du disque I / OS demandé. 100000 N'est-ce pas un multiple de 4Kib, mais les valeurs de 64Kib à 1MIB sont raisonnables.
Selon man code> : p>
dd code> sur FreeBSD
skip = code> n em> p>Passer n em> blocs du début de l'entrée avant de copier. sur l'entrée qui supporte la recherche, une opération LSEOK (2) est utilisée. strong> Sinon, les données d'entrée sont lues et supprimées. Pour les tuyaux, le Le nombre correct d'octets est lu. Pour tous les autres appareils, le Le nombre correct de blocs est lu sans distinction entre un bloc partiel ou complet en cours de lecture. P> blockQuote> blockQuote>
Utilisation
DTRUSS code> J'ai vérifié qu'il utiliselsek () code> sur un fichier d'entrée sur Mac OS X. Si vous pensez simplement que c'est lent, je suis d'accord avec le commentaire que cela serait dû à la taille du bloc de 1 octet. P>
Oui, il est gênant de le faire avec DD aujourd'hui. Nous envisageons d'ajouter Skip_Bytes et Count_Bytes paramètres sur DD dans Coreutils pour vous aider. Ce qui suit devrait fonctionner cependant:
#!/bin/sh bs=100000 infile=$1 skip=$2 length=$3 ( dd bs=1 skip=$skip count=0 dd bs=$bs count=$(($length / $bs)) dd bs=$(($length % $bs)) count=1 ) < "$infile"
Ouais, ajoutant Skip / Count_bytes serait vraiment utile et faire de la DD un but général faciles à utiliser Byte-Grabber :)
Vous pouvez essayer la commande heexdummp: ex.) Lisez 100 octets de 'mycorefile' à partir de décalage 100. p> # /usr/bin/hexdump -v -C mycorefile -n 100 -s 100
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000074 00 00 00 00 01 00 00 00 05 00 00 00 00 10 03 00 |................|
00000084 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 |......@.........|
00000094 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 03 00 |................|
000000a4 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 |................|
000000b4 06 00 00 00 00 10 03 00 00 00 00 00 00 90 63 00 |..............c.|
000000c4 00 00 00 00 |....|
000000c8
#
Je viens d'essayer d'exécuter
strace code> sur DD, il a utilisé llsek.Ah, je suis sur Freebsd, alors peut-être que c'est une implémentation différente. Peut-être que c'est lent car je définissais la taille de la mémoire tampon d'entrée sur 1 octet.