du -h | sort -n 排序错误,因 sort -n 仅按字符串首数字截断比较(如 999k > 1.2g),无法识别单位;必须用 sort -hr 才能正确解析 k/m/g 并逆序排列。

直接用 du -h --max-depth=1 2>/dev/null | sort -hr 就能按人类可读单位降序列出当前目录各子项大小,但必须配 -hr,否则 sort -n 会把 "1G" 和 "500M" 当字符串乱排。
为什么 du -h | sort -n 排序结果总是错的
du -h 输出带单位(如 2.3G、456K),sort -n 只认纯数字开头的行,遇到字母就截断比较,导致 999K 排在 1.2G 前面——因为 999 > 1,而 G 被忽略。这不是 bug,是设计如此。
-
sort -h才识别人类可读单位(K/M/G/T),自动换算成字节数再比大小 -
-r表示逆序,让最大的排最前;不加就升序,最小的在顶上 - 如果系统不支持
sort -h(如旧版 CentOS 6),得用du -B1 | sort -n强制输出字节再排
du 统计范围控制:别让结果被子目录拖慢或污染
默认 du 会递归进每一层子目录,既慢又容易淹没真正的大项。用 --max-depth 限定层级最实用:
-
du -h --max-depth=1:只统计当前目录下一级子目录/文件,适合快速定位“谁占了最多” -
du -sh *:更安全,避开隐藏文件和权限报错,但通配符不匹配以.开头的项 -
du -h --max-depth=1 --exclude=".*":显式跳过隐藏项,比*更可控 - 加
2>/dev/null屏蔽du: cannot read directory类错误,避免干扰排序流
查大文件时,du -a 和 find -type f 的关键区别
想看“单个最大文件”,不是“哪个目录最大”,就不能只用 du --max-depth=1——它统计的是目录总和,一个含 100 个小文件的目录可能排第一,但你真正想删的是那个 5G 的日志。
-
du -ah . | sort -hr | head -n 10:递归列所有文件+目录,-a是关键,但结果混杂,需人工识别 -
find . -type f -exec du -h {} + | sort -hr | head -n 10:只找普通文件,-exec ... +比\;效率高,避免每文件起一次du - 注意
find默认包含隐藏文件,加-not -path "./.*"可排除,否则.cache之类常霸榜
符号链接和跨文件系统带来的偏差
du 默认不跟随符号链接(-P),所以软链接本身只算几个字节;但若用 -L 或 -D,就会把目标文件大小也计入——这可能导致同一路径在不同参数下结果差几倍。
-
du -sh /var/log和du -shL /var/log可能完全不同,后者若/var/log是指向/mnt/bigdisk/logs的软链,就会计入整个挂载点 - 跨文件系统时(比如
/home单独挂载),du -x会停在本文件系统边界,避免误统计其他分区内容 -
--apparent-size显示文件“看起来多大”,对稀疏文件(如虚拟机镜像)比实际磁盘占用小得多,清理前务必确认用的是真实占用还是表观大小
真正难的不是命令拼写,而是想清楚:你要找的是“最大的容器”,还是“最大的单体”;是否接受软链展开;能不能容忍跨分区统计。参数一动,语义就变,别让 head -n 10 遮住了问题本质。











