Como preencher um arquivo no tamanho desejado?

15

Eu tenho um arquivo que desejo preencher até atingir 16 MiB (16777216 bytes). Atualmente, são 16515072 bytes. A diferença é de 262144 bytes.

Como faço para preenchê-lo?

Isso não parece estar funcionando:

cp smallfile.img largerfile.img
dd if=/dev/zero of=largerfile.img bs=1 count=262144
tarabyte
fonte
2
@terabyte; você deseja preenchimento físico ou preenchimento lógico? Em outras palavras; o arquivo deve mostrar apenas um tamanho de 16777216 (e pode conter orifícios) ou também deve ocupar essa quantidade de armazenamento no disco? - BTW, a escolha de um bs=1em ddé na minha experiência muito tempo de execução caro.
Janis
5
truncate -s 16M thefile
Frostschutz 17/04/2015
4
@frostschutz que seria uma boa resposta, você deveria publicá-la como resposta.
derobert
@derobert, O que há com os usuários do site StackExchange postando respostas simples e legítimas como comentários?
user1717828
@ user1717828 não tenho certeza, provavelmente uma boa pergunta para meta.
derobert

Respostas:

10

Solte of=largerfile.txte adicione stdout ao arquivo:

dd if=/dev/zero bs=1 count=262144 >> largerfile.txt
Outurnate
fonte
1
seeké uma opção certa aqui.
0andriy
15

Além das respostas para obter um preenchimento físico, você também pode deixar a maior parte do espaço preenchido no arquivo apenas vazio ("buracos"), seekacessando a nova posição final do arquivo e escrevendo um único caractere:

dd if=/dev/zero of=largerfile.txt bs=1 count=1 seek=16777215

(que tem a vantagem de ter muito mais desempenho, especificamente com bs=1e não ocupa grandes quantidades de espaço em disco adicional).

Esse método parece funcionar mesmo sem adicionar nenhum caractere, usando if=/dev/nulle o tamanho final do arquivo desejado:

dd if=/dev/null of=largerfile.txt bs=1 count=1 seek=16777216

Uma variante de desempenho de uma solução de preenchimento físico que usa tamanhos de bloco maiores é:

padding=262144 bs=32768 nblocks=$((padding/bs)) rest=$((padding%bs))
{
  dd if=/dev/zero bs=$bs count=$nblocks
  dd if=/dev/zero bs=$rest count=1
} 2>/dev/null >>largerfile.txt
Janis
fonte
3
Corrigir. Nesse caso truncate -s +262144 largerfile.txt, também seria rápido.
don_crissti
4

A melhor resposta aqui é a de Janis (acima), pois permite esquecer o tamanho do arquivo atual e ajustar diretamente para o tamanho desejado sem cálculo.

Ele também tira proveito dos arquivos esparsos, que não são adicionados ao / dev / zero.

A resposta pode ser mais organizada, porque 'count' pode ser 0 e você ainda recebe o preenchimento:

dd if=/dev/null of=largerfile.txt bs=1 count=0 seek=16777216

(Edit: isso está correto para o GNU dd, mas o comportamento de count=0é específico da plataforma, consulte os comentários)

PeteC
fonte
Você está enganado: count=0não é especificado, mas geralmente é o mesmo de quando nenhum countparâmetro foi especificado. Mais problemas: ddtrunca o arquivo para 16777216 bytes, mas se você espera que isso crie um furo no final, você está enganado, pois você primeiro precisaria gravar dados após o furo e depois truncá-lo para um tamanho que não contenha dados .
schily
count = 0 não é nada como especificar o parâmetro no count. Você está dizendo que dd if=/dev/zero of=somefileé o mesmo que dd if=/dev/zero of=somefile count=0? Tente.
PETEC
Claro! count=0 é o mesmo que se você não especificou um parâmetro de contagem. Isso é verdade pelo menos para todas as implementações que foram derivadas das fontes originais. Experimente, parece que você nunca trabalhou com o ddcomando original .
schily
Não consigo encontrar nenhuma documentação que especifique 0 como um valor exclusivo para o countsignificado 'ignorar este parâmetro'. Você pode encontrar algum? Sem essa documentação, count=0significa 'escrever zero blocos' e qualquer desvio disso é um bug ... (fontes originais ou não).
PeteC
1
Esta foi a documentação do POSIX anterior a maio de 2015, quando o texto não especificado foi corrigido.
schily
1

Você tem que usar dd? Se você deseja que um arquivo tenha um comprimento (lógico) específico, basta escrever um zero na posição desejada. Os bytes entre o final anterior e o byte gravado serão exibidos como tendo bytes nulos. Aqui está um exemplo usando perl.

$ echo Hello > file
$ ls -l file
-rw-r--r-- 1 user group 6 Apr 16 22:59 file
$ perl -le 'open(my $f,"+<","file"); seek($f, 16777216 - 2, 0); print $f "\0"'
$ ls -ln file
-rw-r--r-- 1 user group 16777216 Apr 16 22:59 file

Por que o "- 2" na linha? O script escreverá um byte, portanto subtraímos 1 para procurar a posição anterior a esse byte. Nós decolamos do outro porque a posição de busca é indexada em zero.

BowlOfRed
fonte