Em sistemas (e sistemas de arquivos) suportando o sinal SEEK_HOLE
lseek
(como seu Ubuntu 12.04 no ext4) (e assumindo que o valor de SEEK_HOLE
é 4 como no Linux):
if perl -le 'seek STDIN,0,4;$p=tell STDIN;
seek STDIN,0,2; exit 1 if $p == tell STDIN'< the-file; then
echo the-file is sparse
else
echo the-file is not sparse
fi
Essa sintaxe do shell é POSIX. As coisas não portáveis são perl
e SEEK_HOLE
.
lseek(SEEK_HOLE)
procura o início do primeiro buraco no arquivo ou o final do arquivo, se nenhum furo for encontrado. Acima sabemos que o arquivo não é esparso quando o lseek(SEEK_HOLE)
nos leva ao final do arquivo (para o mesmo lugar que lseek(SEEK_END)
).
Se você deseja listar os arquivos esparsos:
find . -type f ! -size 0 -exec perl -le 'for(@ARGV){open(A,"<",$_)or
next;seek A,0,4;$p=tell A;seek A,0,2;print if$p!=tell A;close A}' {} +
O% GNUfind
(desde a versão 4.3.3) tem -printf %S
para relatar o sparseness de um arquivo. Ele adota a mesma abordagem da frostschutz 'resposta , pois leva a proporção entre o uso do disco e o tamanho do arquivo. Não é garantido informar todos os arquivos esparsos (como quando há compactação no nível do sistema de arquivos ou onde o espaço salvo pelos furos não compensa a sobrecarga da infraestrutura do sistema de arquivos ou grandes atributos estendidos), mas funcionaria em sistemas que não possuem SEEK_HOLE
ou sistemas de arquivos em que SEEK_HOLE
não está implementado. Aqui com ferramentas GNU:
find . -type f ! -size 0 -printf '%S:%pif perl -le 'seek STDIN,0,4;$p=tell STDIN;
seek STDIN,0,2; exit 1 if $p == tell STDIN'< the-file; then
echo the-file is sparse
else
echo the-file is not sparse
fi
' |
awk -v RS='find . -type f ! -size 0 -exec perl -le 'for(@ARGV){open(A,"<",$_)or
next;seek A,0,4;$p=tell A;seek A,0,2;print if$p!=tell A;close A}' {} +
' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'
(observe que uma versão anterior dessa resposta não funcionou corretamente quando find
expressou a dispersão como, por exemplo, 3.2e-05. Graças a @ flashydave responder por chamar minha atenção para isso