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

28

¿Cómo hacer algo así dd if=somefile bs=1 skip=1337 count=31337000, pero eficientemente, sin usar lecturas y escrituras que no sean de 1 byte?

La solución se espera:

  1. Para ser simple (para los no simples, puedo escribir una línea de Perl que haga esto)
  2. Para admitir grandes compensaciones y longitudes (por lo que los hacks con tamaño de bloque en dd no ayudarán)

Solución parcial (no 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
Vi.
fuente
¿Estás tratando de cambiar el tamaño de bloque que está usando dd?
cmorse
Tamaño de bloque modificado => unidades modificadas para saltar y contar
Vi.

Respuestas:

37

Esto debería hacerlo (en gnu dd):

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

En caso de que estés usando seek= también, también puede 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'.

PD: Entiendo que esta pregunta es antigua y parece que estas banderas se implementaron después de que la pregunta se hizo originalmente, pero como 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.

Fabiano
fuente
2

Use 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 encuentre eficiente. Tenga en cuenta que esto requiere un proceso adicional para generar; dependiendo de su sistema operativo que tendrá un costo, pero probablemente sea más pequeño que tener que leer los archivos de uno en uno (a menos que tenga un archivo muy pequeño, en cuyo caso no habría ningún problema).

RolKau
fuente
¿Funcionará bien (es decir, no acumule demasiada memoria) para grandes compensaciones y recuentos? dd if=/dev/sda bs=10000000001 | dd bs=255 count=1 | hd-> "dd: número inválido '10000000001'"
Vi.
@Vi. Si desea omitir un gran desplazamiento, entonces debe hacer la lectura inicial como una serie de bloques de tamaño "idealmente" (dependiendo de su fuente) (16M), luego suelte una serie de bloques de menor tamaño (512) que estarán en la memoria , para "acercar" sus datos, antes de dejar una partición impar que no se ajusta al tamaño del bloque (bs = 1 a continuación) y luego leer el bloque que desee. Por ejemplo, desea leer 255 bytes del desplazamiento 10000000001: dd if=/dev/sda bs=16M skip=596 count=1 | dd bs=512 skip=1522 count=1 | (dd bs=1 count=1 of=/dev/null ; dd bs=255 count=1)
RolKau
¿Seguramente sería más fácil de usar read -npara saltar? ¿Y luego head -ccontar? Por ejemplo, cat somefile | (read -n 1337; head -c 31337000)o podría hacerlo sin generar un proceso adicional:exec 3<somefile; read -n 1337 -u 3; head -c 31337000 <&3
Gannet
1

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

ccpizza
fuente
2
Luego leerá desde el desplazamiento 1337 * 4096 en lugar de 1337
Vi.
1
Ajá, ya veo, entonces probablemente será más fácil escribir un script Python simple, por ejemplo, como en este ejemplo stackoverflow.com/questions/1035340/... con f.seek(1337)antes de usarread(MY_CHUNK_SIZE)
ccpizza
Parece que la forma más confiable es probablemente escribir un ejecutable personalizado. Algunos sistemas no tienen Python, ni Ruby, ni siquiera Perl. : |
Trejkaz
1

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 #
Saravanan Palanisamy
fuente
No se trata de ver el archivo como hexadecimal. Se trata de extraer el contenido de un archivo (para copiarlo en algún lugar, por ejemplo) del desplazamiento especificado en bytes.
Vi.