SEEK_HOLE
lseek
Bayrağı destekleyen sistemlerde (ve ext4'teki Ubuntu 12.04 gibi) ve SEEK_HOLE
Linux'ta olduğu gibi 4 olduğu varsayıldığında :
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
Bu kabuk sözdizimi POSIX. İçinde taşınabilir olmayan şeyler perl
ve bu SEEK_HOLE
.
lseek(SEEK_HOLE)
dosyadaki ilk deliğin başlangıcını veya hiçbir delik bulunmazsa dosyanın sonunu arar . Yukarıda bizi dosyanın lseek(SEEK_HOLE)
sonuna götürdüğünde ( seyrek olarak) dosyanın seyrek olmadığını biliyoruz lseek(SEEK_END)
.
Seyrek dosyaları listelemek istiyorsanız:
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}' {} +
GNU find
(sürüm 4.3.3'ten beri) bir dosyanın seyrekliğini-printf %S
rapor etmek zorundadır . Aynı yaklaşımı benimserDisk kullanımının dosya boyutuna oranını alması nedeniyle frostschutz'un cevabı ile benimser , bu nedenle tüm seyrek dosyaları bildirmesi garanti edilmez (dosya sistemi düzeyinde sıkıştırma olduğunda veya deliklerin kaydettiği alanın olmadığı gibi) dosya sistemi altyapısı yükünü veya büyük genişletilmiş öznitelikleri telafi eder), ancak olmayan SEEK_HOLE
sistemlerde veya SEEK_HOLE
uygulanmayan dosya sistemlerinde çalışır . İşte GNU araçlarıyla:
find . -type f ! -size 0 -printf '%S:%p\0' |
awk -v RS='\0' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'
(bu cevabın önceki bir versiyonunun, find
örneğin 3.2e-05 gibi seyreklik ifade edildiğinde düzgün çalışmadığını unutmayın. @ flashydave'nin cevabı sayesinde )