AFAIK é (infelizmente) não é possível truncar um arquivo desde o início (isso pode ser verdade para as ferramentas padrão, mas para o nível syscall veja aqui ). Mas, adicionando alguma complexidade, você pode usar o truncamento normal (junto com arquivos esparsos): Você pode escrever no final do arquivo de destino sem ter escrito todos os dados entre eles.
Vamos assumir primeiro que ambos os arquivos sejam exatamente 5GiB (5120 MiB) e que você queira mover 100 MiB por vez. Você executa um loop que consiste em- copiando um bloco do final do arquivo de origem para o final do arquivo de destino (aumentando o espaço em disco consumido)
-
truncando o arquivo de origem em um bloco (liberando espaço em disco)
for((i=5119;i>=0;i--)); do dd if=sourcefile of=targetfile bs=1M skip="$i" seek="$i" count=1 dd if=/dev/zero of=sourcefile bs=1M count=0 seek="$i" done
Mas experimente primeiro com arquivos de teste menores, por favor ...
Provavelmente, os arquivos não são do mesmo tamanho nem múltiplos do tamanho do bloco. Nesse caso, o cálculo das compensações torna-se mais complicado. seek_bytes
e skip_bytes
devem ser usados.
Se esta é a maneira que você quer ir, mas precisar de ajuda para os detalhes, pergunte novamente.
Aviso
Dependendo do tamanho do bloco dd
, o arquivo resultante será um pesadelo de fragmentação.