Hoje eu tive que remover os primeiros 1131 bytes de um arquivo de texto / binário de 800 MB, um despejo de subversão filtrado que estou procurando por um novo repositório. Qual é a melhor forma de fazer isso?
Para começar, tentei
dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump
mas após o salto, ele copia o restante do arquivo, um byte de cada vez, ou seja, muito lentamente. No final, resolvi que precisava de 405 bytes para arredondar até três blocos de 512 que eu poderia pular
dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump
que foi concluído rapidamente, mas deve ter havido uma maneira mais simples / melhor? Existe outra ferramenta que eu esqueci? Obrigado!
dd
é a ferramenta certa para o trabalho - parece que você encontrou uma solução agradável e elegante para o seu problema.Respostas:
Você pode alternar as opções bs e pular:
Dessa forma, a operação pode se beneficiar de um bloco maior.
Caso contrário, você pode tentar com tail (embora não seja seguro usá-lo com arquivos binários):
Finalmente, você pode usar 3 instâncias dd para escrever algo como isto:
onde o primeiro dd imprime sua saída padrão filtrada.dump; o segundo apenas lê 1131 bytes e os joga fora; então, o último lê da entrada padrão os bytes restantes de filter.dump e grava-os em trimmed.dump.
fonte
bs=1131 skip=1
: - /Não tem certeza de quando
skip_bytes
foi adicionado, mas para pular os 11 primeiros bytes que você possui:Onde
iflag=skip_bytes
diz ao dd para interpretar o valor daskip
opção como bytes em vez de blocos, tornando-o simples.fonte
iflag=skip_bytes skip=1234 bs=1M
Você pode usar um sub-shell e duas
dd
chamadas como esta:fonte
Se o sistema de arquivos e o kernel Linux o suportarem, você pode tentar
fallocate
se deseja fazer as alterações no local: na melhor das hipóteses, não há IO de dados:onde
<magic>
depende do sistema de arquivos, da versão Linux e do tipo de arquivo (FALLOC_FL_COLLAPSE_RANGE
ouFALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE
pode ser usado internamente ).fonte
Você deve usar
count=0
- isso é simpleslseek()
sempre que possível.Como isso:
dd
farálseek()
o descritor do arquivo de entrada para um deslocamento de 1131 bytes e, em seguidacat
, simplesmente copiará o que restar na saída.fonte
Ainda outra maneira de remover os bytes iniciais de um arquivo (sem usar
dd
nada) é usarxxd
esed
outail
respectivamente.fonte
@maxschlepzig pede um forro online. Aqui está um em perl. É preciso 2 argumentos: de byte e comprimento. O arquivo de entrada deve ser fornecido por '<' e a saída estará no stdout:
Se o comprimento for maior que o arquivo, o restante do arquivo será copiado.
No meu sistema, isso oferece 3,5 GB / s.
fonte
dd
não garante uma leitura completa. Tente: sim | dd bs = contagem de 1024k = 10 | wc unix.stackexchange.com/questions/17295/…