Trên các hệ thống (và hệ thống tệp) hỗ trợ SEEK_HOLE
lseek
cờ (như Ubuntu 12.04 của bạn trên ext4) và giả sử giá trị SEEK_HOLE
là 4 như trên 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
Cú pháp shell đó là POSIX. Các công cụ không di động trong đó là perl
và đó SEEK_HOLE
.
lseek(SEEK_HOLE)
tìm kiếm điểm bắt đầu của lỗ đầu tiên trong tệp hoặc cuối tệp nếu không tìm thấy lỗ. Ở trên chúng ta biết tệp không thưa thớt khi lseek(SEEK_HOLE)
đưa chúng ta đến cuối tệp (đến cùng một nơi với lseek(SEEK_END)
).
Nếu bạn muốn liệt kê các tập tin thưa thớt:
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
(kể từ phiên bản 4.3.3) -printf %S
phải báo cáo độ thưa của tệp. Nó có cách tiếp cận giống như câu trả lời của frostschutz ở chỗ nó lấy tỷ lệ sử dụng đĩa so với kích thước tệp, do đó không được đảm bảo báo cáo tất cả các tệp thưa thớt (như khi nén ở cấp hệ thống tệp hoặc nơi không gian được lưu bởi các lỗ không bù cho chi phí cơ sở hạ tầng hệ thống tập tin hoặc các thuộc tính mở rộng lớn), nhưng sẽ hoạt động trên các hệ thống không có SEEK_HOLE
hoặc hệ thống tệp SEEK_HOLE
không được triển khai. Ở đây có các công cụ GNU:
find . -type f ! -size 0 -printf '%S:%p\0' |
awk -v RS='\0' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'
(lưu ý rằng phiên bản trước của câu trả lời này không hoạt động chính xác khi find
thể hiện độ thưa như ví dụ 3.2e-05. Cảm ơn câu trả lời của @ flashydave đã khiến tôi chú ý)