web-dev-qa-db-fra.com

Comment sortir le fichier du décalage spécifié, mais pas "dd bs = 1 skip = N"?

Comment faire des choses comme dd if=somefile bs=1 skip=1337 count=31337000, mais efficacement, en n'utilisant pas des lectures et écritures sur 1 octet?

La solution est attendue:

  1. Pour être simple (pour les non-simples je peux écrire du Perl oneliner qui le fera)
  2. Pour prendre en charge des décalages et des longueurs importants (les hacks avec une taille de bloc dans jj ne vous aideront pas)

Solution partielle (pas assez simple, essayer la même chose avec la longueur le rendra encore plus complexe):

dd if=somefile bs=1000 skip=1 count=31337 | { dd bs=337 count=1 of=/dev/null; rest_of_pipeline; }
# 1337 div 1000 and 1337 mod 1000
25
Vi.

Cela devrait le faire (sur gnu dd):

dd if=somefile bs=4096 skip=1337 count=31337000 iflag=skip_bytes,count_bytes

Si vous utilisez également seek=, vous pouvez également envisager oflag=seek_bytes.

De info dd:

`count_bytes'
      Interpret the `count=' operand as a byte count, rather than a
      block count, which allows specifying a length that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`skip_bytes'
      Interpret the `skip=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`seek_bytes'
      Interpret the `seek=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `oflag'.

Ps: Je comprends que cette question est ancienne et il semble que ces drapeaux aient été mis en œuvre après que la question a été posée à l'origine, mais comme c'est l'un des premiers résultats de Google pour une recherche connexe jj, je l'ai fait ce serait bien de mettre à jour avec la nouvelle fonctionnalité.

36
Fabiano

Utilisez un processus pour supprimer tous les octets initiaux, puis un second pour lire les octets réels, par exemple:

echo Hello, World\! | ( dd of=/dev/null bs=7 count=1 ; dd bs=5 count=1 )

La seconde dd peut lire l'entrée avec la taille de bloc que vous trouvez efficace. Notez que cela nécessite un processus supplémentaire pour être généré; cela dépendra de votre système d'exploitation, mais cela coûtera probablement moins cher que de lire les fichiers un par un (octet par octet) (sauf si vous avez un très petit fichier, auquel cas il n'y aurait pas de problème).

2
RolKau

Au lieu de bs=1, utilisez bs=4096 ou plus.

1
ccpizza

Vous pouvez essayer la commande hexdump:

hexdump  -v <File Path> -c -n <No of bytes to read> -s <Start Offset>

Si vous voulez simplement voir le contenu:

#/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 #
0