Files
.dotfile/script/dirsize.sh
T
laily 67291a9a50 feat: add script catalog and -h help for all dotfile scripts
Introduce ff script -h with auto descriptions, shared help.sh, and usage flags across script/*.sh.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 15:09:35 +08:00

132 lines
2.8 KiB
Bash
Executable File

#!/bin/bash
# 查询目录大小(du 封装,支持排序与 Top N)
set -eu
usage() {
cat <<'EOF'
用法: dirsize [选项] [目录]
查询目录大小,默认列出当前目录下的直接子目录和子文件。
选项:
-a, --all 递归显示所有子目录的大小
-d, --depth N 指定递归深度 (默认 1)
-n, --top N 只显示前 N 名 (默认全部)
-r, --reverse 按从小到大排序 (默认从大到小)
-h, --help 显示帮助信息
示例:
dirsize 当前目录的直接子项大小
dirsize -n 10 当前目录的直接子项,取前 10 名
dirsize -a 递归显示所有子目录
dirsize -d 2 -n 5 深度 2,取前 5 名
dirsize -n 5 /var/log 查看 /var/log 的子项,取前 5 名
EOF
exit 0
}
DEPTH=1
TOP=0
REVERSE=false
ALL=false
TARGET_DIR="."
while [[ $# -gt 0 ]]; do
case "$1" in
-a | --all)
ALL=true
shift
;;
-d | --depth)
DEPTH="$2"
shift 2
;;
-n | --top)
TOP="$2"
shift 2
;;
-r | --reverse)
REVERSE=true
shift
;;
-h | --help) usage ;;
-*)
echo "未知选项: $1" >&2
usage
;;
*)
TARGET_DIR="$1"
shift
;;
esac
done
if [[ ! -d "$TARGET_DIR" ]]; then
echo "错误: '$TARGET_DIR' 不是有效目录" >&2
exit 1
fi
TARGET_DIR="$(cd "$TARGET_DIR" && pwd -P)"
if $ALL; then
DEPTH=999
fi
sort_flag="-rh"
if $REVERSE; then
sort_flag="-h"
fi
list_dir_sizes() {
if [[ "$OSTYPE" == "darwin"* ]]; then
sudo du -h -d "$DEPTH" "$TARGET_DIR" 2>/dev/null
else
sudo du -h --max-depth="$DEPTH" "$TARGET_DIR" 2>/dev/null
fi | awk -v dir="$TARGET_DIR" '$2 != dir {print}'
}
# 用 ls 读取直接子文件(一次 readdir),避免 find 递归
list_direct_file_sizes() {
sudo ls -lA "$TARGET_DIR" 2>/dev/null | awk -v dir="$TARGET_DIR" '
function human(bytes, units, i, size) {
split("B K M G T", units, " ")
i = 1
size = bytes
while (size >= 1024 && i < 5) {
size /= 1024
i++
}
if (i == 1) {
return sprintf("%dB", bytes)
}
return sprintf("%.1f%s", size, units[i])
}
/^-/ {
name = $9
for (i = 10; i <= NF; i++) {
name = name " " $i
}
printf "%s\t%s/%s\n", human($5), dir, name
}
'
}
result=$(
{
list_dir_sizes
list_direct_file_sizes
} | sort $sort_flag
)
if [[ "$TOP" -gt 0 ]]; then
result=$(echo "$result" | head -n "$TOP")
fi
if [[ -z "$result" ]]; then
echo "目录为空"
exit 0
fi
echo "$result"