¿Cómo generar un archivo desde el desplazamiento especificado, pero no "dd bs=1 skip=N"?

¿Cómo generar un archivo desde el desplazamiento especificado, pero no "dd bs=1 skip=N"?

¿Cómo hacer algo así dd if=somefile bs=1 skip=1337 count=31337000, pero de manera eficiente, sin utilizar lecturas y escrituras de 1 byte?

Se espera la solución:

  1. Para ser simple (para los que no son simples, puedo escribir un esquema en Perl que haga esto)
  2. Para admitir desplazamientos y longitudes grandes (por lo que los trucos con tamaño de bloque en dd no ayudarán)

Solución parcial (no es lo suficientemente simple, intentar lo mismo con la longitud lo hará aún más complejo):

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

Respuesta1

Esto debería bastar (en gnu dd):

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

En caso de que también estés usando seek=, también puedes considerar 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: entiendo que esta pregunta es antigua y parece que estos indicadores se implementaron después de que se formuló originalmente la pregunta, pero dado que es uno de los primeros resultados de Google para una búsqueda de dd relacionada que hice, pensé que sería bueno actualizar con la nueva característica.


Nota: esta respuesta se aplica sólo aGNU dd, utilizado por la mayoría de las distribuciones de Linux, es parte dePaquete GNU coreutils, esta característica se introdujo en la versión 8.16 de Coreutils (26 de marzo de 2012, un par de meses después de que se respondió la pregunta original).

Nota paraUsuarios de Mac: MacOS usa una variante de utilidades Unix basada en BSD (principalmente por razones de licencia), pero las versiones GNU de utilidades Unix en general tienen un desarrollo mucho más activo y generalmente tienen muchas más funciones. Puede instalar GNU coreutils en Mac concerveza casera: brew install coreutils.

Respuesta2

Utilice un proceso para deshacerse de todos los bytes iniciales, luego un segundo para leer los bytes reales, por ejemplo:

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

El segundo ddpuede leer la entrada con cualquier tamaño de bloque que considere eficiente. Tenga en cuenta que esto requiere que se genere un proceso adicional; Dependiendo de su sistema operativo, esto generará un costo, pero probablemente sea menor que tener que leer los archivos uno por uno (a menos que tenga un archivo muy pequeño, en cuyo caso no habría ningún problema).

Respuesta3

En lugar de bs=1usar bs=4096o más.

Respuesta4

Puedes probar el comando hexdump:

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

Si simplemente quieres ver el contenido:

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

información relacionada