Editar 2015
a partir do util-linux 2.25, o utilitário fallocate
no Linux tem uma opção -d
/ --dig-hole
para isso.
fallocate -d the-file
Cavaria um buraco para cada bloco cheio de zeros no arquivo
Em sistemas mais antigos, você pode fazer isso manualmente:
O Linux tem uma opção FALLOC_FL_PUNCH_HOLE
para fallocate
que pode fazer isso. Eu encontrei um script no github com um exemplo:
Usando o FALLOC_FL_PUNCH_HOLE do Python
Eu modifiquei um pouco para fazer o que você pediu - faça furos em regiões de arquivos preenchidos com zeros. Aqui está:
Usando o FALLOC_FL_PUNCH_HOLE do Python para fazer furos nos arquivos
usage: punch.py [-h] [-v VERBOSE] FILE [FILE ...]
Punch out the empty areas in a file, making it sparse
positional arguments:
FILE file(s) to modify in-place
optional arguments:
-h, --help show this help message and exit
-v VERBOSE, --verbose VERBOSE
be verbose
Exemplo:
# create a file with some data, a hole, and some more data
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=0
$ dd if=/dev/urandom of=test1 bs=4096 count=1 seek=2
# see that it has holes
$ du --block-size=1 --apparent-size test1
12288 test1
$ du --block-size=1 test1
8192 test1
# copy it, ignoring the hole
$ cat test1 > test2
$ du --block-size=1 --apparent-size test2
12288 test2
$ du --block-size=1 test2
12288 test2
# punch holes again
$ ./punch.py test2
$ du --block-size=1 --apparent-size test2
12288 test2
$ du --block-size=1 test2
8192 test2
# verify
$ cmp test1 test2 && echo "files are the same"
files are the same
Observe que punch.py
só encontra blocos de 4096 bytes para perfurar, portanto, pode não tornar um arquivo exatamente tão esparso quanto era quando você começou. Poderia ser mais inteligente, é claro. Além disso, é apenas ligeiramente testado , por isso tome cuidado e faça backups antes de confiar nele!