Auf Systemen (und Dateisystemen), die das SEEK_HOLE
lseek
Flag unterstützen (wie bei Ubuntu 12.04 unter ext4) und den Wert SEEK_HOLE
4 annehmen, wie dies unter Linux der Fall ist:
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
Diese Shell-Syntax lautet POSIX. Die nicht tragbaren Dinge darin sind perl
und das SEEK_HOLE
.
lseek(SEEK_HOLE)
Sucht nach dem Anfang des ersten Lochs in der Datei oder nach dem Ende der Datei, wenn kein Loch gefunden wird. Oben wissen wir, dass die Datei nicht spärlich ist, wenn sie lseek(SEEK_HOLE)
uns zum Ende der Datei führt (an die gleiche Stelle wie lseek(SEEK_END)
).
Wenn Sie die Sparse-Dateien auflisten möchten:
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}' {} +
Die GNU find
(seit Version 4.3.3) muss -printf %S
die Kargheit einer Datei melden . Dies entspricht dem Ansatz von frostschutz, bei dem das Verhältnis von Datenträgernutzung zu Dateigröße berücksichtigt wird. Es kann daher nicht garantiert werden, dass alle Dateien mit geringer Speicherkapazität gemeldet werden (z. B. wenn die Komprimierung auf Dateisystemebene erfolgt oder der durch die Lücken gespeicherte Speicherplatz nicht Kompensieren Sie den Overhead der Dateisysteminfrastruktur (oder große erweiterte Attribute), funktionieren Sie jedoch auf Systemen ohne SEEK_HOLE
oder auf Dateisystemen, auf denen dies SEEK_HOLE
nicht implementiert ist. Hier mit GNU-Tools:
find . -type f ! -size 0 -printf '%S:%p\0' |
awk -v RS='\0' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'
(Beachten Sie, dass eine frühere Version dieser Antwort nicht richtig funktionierte, wenn find
die Kargheit ausgedrückt wurde, wie zum Beispiel 3.2e-05. Vielen Dank an @ flashydaves Antwort , dass Sie mich darauf aufmerksam gemacht haben.)