Use `dd` para cortar a parte final do arquivo

18

Provavelmente existe um truque simples para fazer isso, mas não consigo descobrir na página do manual.

Como recortar 1 MB do arquivo com tamanho indeterminado, por exemplo, usando dd?

zetah
fonte
11
Você deseja uma cópia desse arquivo, exceto os últimos 1 MB, ou deseja que o último MB seja copiado para outro arquivo?
28412 Mat
Quero último 1MB
zetah 28/02

Respostas:

29

Bem, supondo que você tenha state bash, você pode obter o tamanho do arquivo com:

stat -c %s your_file

Se você deseja extrair os últimos $amountbytes desse arquivo dd, pode:

dd if=your_file of=extracted_part \
   bs=1 count=$amount \
   skip=$(( $(stat -c %s your_file) - $amount ))

Mas a abordagem mais saudável seria usar tail:

tail -c $(( 1024*1024 )) your_file > target_file
Esteira
fonte
Nenhuma -copção para head?
ADTC
Eu acho que ele quis dizer + $ ((1024 * 1024)): -c, --bytes = K produz os últimos K bytes; alternativamente, use -c + K para gerar bytes começando com o Kth de cada arquivo #
Vanuan
5
dd --help
Uso: dd [OPERANDO] ...
  ou: dd OPTION
Copie um arquivo, convertendo e formatando de acordo com os operandos.

  bs = BYTES lê e grava bytes de BYTES por vez (consulte também ibs =, obs =)
  cbs = BYTES converte bytes de bytes de cada vez
  conv = CONVS converte o arquivo de acordo com a lista de símbolos separados por vírgula
  count = BLOCKS copia somente blocos de entrada BLOCKS
  ibs = BYTES lê bytes BYTES por vez (padrão: 512)
  if = FILE lido de FILE em vez de stdin
  iflag = FLAGS lidos de acordo com a lista de símbolos separados por vírgula
  obs = BYTES grava bytes de BYTES por vez (padrão: 512)
  of = FILE grava em FILE em vez de stdout
  oflag = FLAGS gravam de acordo com a lista de símbolos separados por vírgula
  seek = BLOCKS pula BLOCKS blocos de tamanho obsoleto no início da saída
  skip = BLOCKS pula BLOCKS blocos de tamanho ibs no início da entrada
  status = noxfer suprimir estatísticas de transferência

BLOCOS e BYTES podem ser seguidos pelos seguintes sufixos multiplicativos:
c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, xM = M
GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024 e assim por diante para T, P, E, Z, Y.

Se o tamanho do arquivo for exatamente 10 MB, 1024 * 10 10240K Isso deixará os últimos 1024K. Você deve especificar o tamanho do bloco com o qual está trabalhando usando as opções ibs e obs.

1M = 1024K 
1024*9 = 9216  
dd if=/10/MB/file of=/9/MB/file count=9216K ibs=1K obs=1K
dd if=/10/MB/file of=/9/MB/file count=9M ibs=1M obs=1M

Você também pode pular o primeiro 1 MB de um arquivo, usando a opção pular para ler até o final do arquivo, pulando o primeiro 1 MB.

dd if=/10/MB/file of=/9/MB/file skip=1M ibs=1M obs=1M

Usando a opção de busca, você pode gravar um em um local específico no seu arquivo de saída. Digamos que você queira manter os primeiros 1 MB e mais de 8 MB.

dd if=/10/MB/file of=/9/MB/file skip=1M seek=1M count=8M ibs=1M obs=1M

Você provavelmente precisará obter alguns detalhes sobre o tamanho do arquivo para garantir a entrada e saída da quantidade certa de dados.

ls -s --block-size 1K ./my/10MB/file
homem sl

       --block-size = SIZE
              use blocos de tamanho SIZE. Veja o formato SIZE abaixo

       -s, --size
              imprime o tamanho alocado de cada arquivo, em blocos

       SIZE pode ser (ou pode ser um número inteiro opcionalmente seguido por) um dos seguintes
       KB 1000, K 1024, MB 1000 * 1000, M 1024 * 1024 e assim por diante para G, T,
       P, E, Z, Y.
nelaaro
fonte