Sur les systèmes (et systèmes de fichiers) prenant en charge l' SEEK_HOLE
lseek
indicateur (comme le ferait votre Ubuntu 12.04 sur ext4) et supposant que la valeur de SEEK_HOLE
est 4 comme sur 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
Cette syntaxe shell est POSIX. Les trucs non portables sont dedans perl
et ça SEEK_HOLE
.
lseek(SEEK_HOLE)
cherche au début du premier trou dans le fichier, ou à la fin du fichier si aucun trou n'est trouvé. Ci-dessus, nous savons que le fichier n'est pas rare lorsque le lseek(SEEK_HOLE)
nous amène à la fin du fichier (au même endroit que lseek(SEEK_END)
).
Si vous souhaitez répertorier les fichiers épars:
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}' {} +
Le GNU find
(depuis la version 4.3.3) doit -printf %S
signaler la rareté d'un fichier. Il adopte la même approche que la réponse de frostschutz en ce qu'il prend le rapport entre l'utilisation du disque et la taille du fichier, il n'est donc pas garanti de signaler tous les fichiers épars (comme lorsqu'il y a compression au niveau du système de fichiers ou lorsque l'espace économisé par les trous ne le fait pas). compenser la surcharge de l'infrastructure du système de fichiers ou les grands attributs étendus), mais fonctionnerait sur des systèmes qui n'en ont pas SEEK_HOLE
ou sur des systèmes de fichiers où il SEEK_HOLE
n'est pas implémenté. Ici avec les outils GNU:
find . -type f ! -size 0 -printf '%S:%p\0' |
awk -v RS='\0' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'
(notez qu'une version antérieure de cette réponse ne fonctionnait pas correctement lorsqu'elle find
exprimait la rareté comme par exemple 3.2e-05. Merci à la réponse de @ flashydave de l' avoir portée à mon attention)