บนระบบ (และระบบไฟล์) ที่สนับสนุนการSEEK_HOLE
lseek
ตั้งค่าสถานะ (เช่น Ubuntu 12.04 ของคุณใน ext4 จะ) และสมมติว่าค่าสำหรับSEEK_HOLE
4 เท่ากับบน 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
ไวยากรณ์เชลล์นั้นคือ 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}' {} +
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}'
(โปรดทราบว่ารุ่นก่อนหน้าของคำตอบนี้ไม่ทำงานอย่างถูกต้องเมื่อfind
แสดงความกระจัดกระจายเช่น 3.2e-05 ขอบคุณคำตอบของ @ flashydave ที่นำมาให้ฉัน)