Em sistemas (e sistemas de arquivos) que suportam a SEEK_HOLE lseekflag (como o Ubuntu 12.04 no ext4 suportaria ) e assumindo que o valor para 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. O material não portátil nele é perle aquilo SEEK_HOLE.
lseek(SEEK_HOLE)procura o início do primeiro furo no arquivo ou o final do arquivo se nenhum buraco for encontrado. Acima, sabemos que o arquivo não é escasso quando nos lseek(SEEK_HOLE)leva ao final do arquivo (no mesmo local 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 GNU find(desde a versão 4.3.3) deve -printf %Srelatar a escassez de um arquivo. Ele segue a mesma abordagem da resposta de frostschutz, na medida em que leva a proporção de uso do disco e tamanho do arquivo, por isso não é garantido que todos os arquivos esparsos sejam reportados (como quando há compressão no nível do sistema de arquivos ou onde o espaço economizado pelos furos não é compensar a sobrecarga da infraestrutura do sistema de arquivos ou grandes atributos estendidos), mas funcionaria em sistemas que não possuem SEEK_HOLEou sistemas de arquivos onde SEEK_HOLEnão são implementados. Aqui com as ferramentas GNU:
find . -type f ! -size 0 -printf '%S:%p\0' |
awk -v RS='\0' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'
(observe que uma versão anterior desta resposta não funcionou corretamente quando findexpressa a escassez como, por exemplo, 3.2e-05. Obrigado à resposta do @ flashydave por chamar a atenção)