Como gerar o arquivo do deslocamento especificado, mas não “dd bs=1 skip=N”?

Como gerar o arquivo do deslocamento especificado, mas não “dd bs=1 skip=N”?

Como fazer algo parecido dd if=somefile bs=1 skip=1337 count=31337000, mas de forma eficiente, sem usar leituras e gravações de 1 byte?

A solução é esperada:

  1. Para ser simples (para não simples, posso escrever um oneliner Perl que fará isso)
  2. Para suportar grandes deslocamentos e comprimentos (portanto, hacks com tamanho de bloco em dd não ajudarão)

Solução parcial (não é simples o suficiente, tentar o mesmo com comprimento tornará ainda mais complexo):

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

Responder1

Isso deve bastar (no gnu dd):

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

Caso você seek=também esteja usando, você também pode 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: Entendo que esta pergunta é antiga e parece que esses sinalizadores foram implementados depois que a pergunta foi feita originalmente, mas como é um dos primeiros resultados do Google para uma pesquisa dd relacionada que fiz, achei que seria bom atualizar com o novo recurso.


Nota: esta resposta se aplica apenas aGNUdd, usado pela maioria das distribuições Linux, faz parte doPacote GNU coreutils, esse recurso foi introduzido na versão 8.16 do coreutils (26/03/2012, alguns meses após a pergunta original ter sido respondida).

Nota paraUsuários de Mac: MacOS usa uma variante baseada em bsd de utilitários unix (principalmente por motivos de licenciamento), mas as versões GNU de utilitários unix em geral têm um desenvolvimento muito mais ativo e geralmente têm muito mais recursos. Você pode instalar GNU coreutils no Mac comCerveja caseira: brew install coreutils.

Responder2

Use um processo para eliminar todos os bytes iniciais e, em seguida, um segundo para ler os bytes reais, por exemplo:

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

O segundo ddpode ler a entrada com qualquer tamanho de bloco que você achar eficiente. Observe que isso requer a geração de um processo extra; dependendo do seu sistema operacional, isso terá um custo, mas provavelmente será menor do que ter que ler os arquivos um por um byte (a menos que você tenha um arquivo muito pequeno, caso em que não haveria problema).

Responder3

Em vez de bs=1usar bs=4096ou mais.

Responder4

Você pode tentar o comando hexdump:

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

Se você simplesmente quiser ver o conteúdo:

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

informação relacionada