And*_*ier 21 filesystems files
是否有一种直接的方法可以在我的系统或特定目录树中查找所有稀疏文件?
如果相关,我zsh在 Ubuntu 12.04 上使用,尽管例如 bash/sh 的更通用的 Unix-y 答案会很好。
编辑:澄清一下,我正在寻找稀疏文件,而不是检查单个文件的稀疏状态。
Sté*_*las 13
在支持该SEEK_HOLE lseek标志的系统(和文件系统)上(例如 ext4 上的 Ubuntu 12.04),并假设它的值为SEEK_HOLE4,就像在 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
Run Code Online (Sandbox Code Playgroud)
该 shell 语法是 POSIX。其中不可携带的东西perl是SEEK_HOLE.
lseek(SEEK_HOLE)查找文件中第一个孔的开头,如果未找到孔,则查找文件的结尾。上面我们知道当lseek(SEEK_HOLE)将我们带到文件末尾(与 相同的位置lseek(SEEK_END))时,文件不是稀疏的。
如果要列出稀疏文件:
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}' {} +
Run Code Online (Sandbox Code Playgroud)
GNU find(从 4.3.3 版开始)必须-printf %S报告文件的稀疏性。它采用与frostschutz 的回答相同的方法,因为它采用磁盘使用率与文件大小的比率,因此不能保证报告所有稀疏文件(例如在文件系统级别进行压缩时或孔节省的空间不补偿文件系统基础架构开销或大型扩展属性),但可以在没有实现的SEEK_HOLE系统或未实现的文件系统上工作SEEK_HOLE。这里有 GNU 工具:
find . -type f ! -size 0 -printf '%S:%p\0' |
awk -v RS='\0' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'
Run Code Online (Sandbox Code Playgroud)
(请注意,此答案的早期版本在find表达稀疏性时无法正常工作,例如 3.2e-05。感谢@flashydave 的回答引起我的注意)
当分配的块数小于文件大小时,文件通常是稀疏的(此处使用statUbuntu 上的 GNU,但要注意其他系统可能具有不兼容的stat)。
if [ "$((`stat -c '%b*%B-%s' -- "$file"`))" -lt 0 ]
then
echo "$file" is sparse
else
echo "$file" is not sparse
fi
Run Code Online (Sandbox Code Playgroud)
变体find:(从斯蒂芬妮那里偷来的)
find . -type f ! -size 0 -exec bash -c '
for f do
[ "$((`stat -c "%b*%B-%s" -- "$f"`))" -lt 0 ] && printf "%s\n" "$f";
done' {} +
Run Code Online (Sandbox Code Playgroud)
你通常会把它放在一个 shell 脚本中,然后执行 shell 脚本。
find . -type f ! -size 0 -exec ./sparsetest.sh {} +
Run Code Online (Sandbox Code Playgroud)
您可以找到%S格式如下的稀疏文件find:
# find / -type f -printf "%S\t%p\n" | gawk '$1 < 1.0 {print}'
0.0139994 /var/log/lastlog
0.959592 /usr/lib/locale/locale-archive
...
Run Code Online (Sandbox Code Playgroud)
在这篇文章中找到它: https://www.thegeekdiary.com/how-to-find-all-the-sparse-file-in-linux/