编写Shell脚本动态遍历指定账号HDFS,查找小文件超10万的目录
遍历HDFS动态深度查找小文件超量目录的Shell脚本
脚本实现
以下脚本支持自定义起始路径、遍历深度、小文件大小阈值以及数量阈值,会递归遍历到指定深度的所有目录,统计其中符合条件的小文件数量,最终输出数量超标的目录路径。
#!/bin/bash # 默认参数配置 START_PATH="/edx/home" # 可替换为你的HDFS起始路径 MAX_DEPTH=3 # 默认遍历深度,可通过参数覆盖 SMALL_FILE_SIZE=$((128 * 1024 * 1024)) # 默认小文件阈值:128MB,可调整 FILE_COUNT_THRESHOLD=100000 # 默认数量阈值:10万 # 解析命令行参数 while getopts "p:d:s:c:" opt; do case $opt in p) START_PATH="$OPTARG" ;; d) MAX_DEPTH="$OPTARG" ;; s) SMALL_FILE_SIZE="$OPTARG" ;; c) FILE_COUNT_THRESHOLD="$OPTARG" ;; \?) echo "无效选项: -$OPTARG" >&2; exit 1 ;; :) echo "选项 -$OPTARG 需要参数" >&2; exit 1 ;; esac done # 递归遍历目录并统计小文件数量 traverse_hdfs() { local current_path=$1 local current_depth=$2 # 当前深度超过设定值则停止递归 if (( current_depth > MAX_DEPTH )); then return fi # 统计当前目录下的小文件数量(排除父目录/当前目录标记,只统计普通文件且大小小于阈值) local file_count=$(hdfs dfs -ls "$current_path" 2>/dev/null | awk -v size="$SMALL_FILE_SIZE" '$5 < size && $NF != "." && $NF != ".." {count++} END {print count+0}') # 数量超过阈值则输出路径 if (( file_count > FILE_COUNT_THRESHOLD )); then echo "目录: $current_path | 小文件数量: $file_count" fi # 遍历子目录继续递归 hdfs dfs -ls "$current_path" 2>/dev/null | awk '$1 ~ /^d/ {print $NF}' | while read -r sub_dir; do traverse_hdfs "$sub_dir" $((current_depth + 1)) done } # 启动遍历,起始深度为1(对应起始路径的层级) traverse_hdfs "$START_PATH" 1
使用说明
参数说明:
-p:指定HDFS起始遍历路径(默认/edx/home)-d:设置最大遍历深度(默认3)-s:设置小文件的大小阈值(单位字节,默认128MB即134217728)-c:设置小文件数量阈值(默认100000)
示例命令:
- 使用默认参数遍历:
bash hdfs_small_file_check.sh - 自定义起始路径、深度为2,数量阈值为8万:
bash hdfs_small_file_check.sh -p /edx/home -d 2 -c 80000 - 自定义小文件阈值为64MB(67108864字节):
bash hdfs_small_file_check.sh -s 67108864
- 使用默认参数遍历:
注意事项
- 确保你的服务账号有对应HDFS目录的
read权限,无权限目录会被自动跳过 - 若HDFS目录结构庞大,遍历耗时较长,建议在非高峰时段执行
- 脚本依赖HDFS默认的
hdfs dfs -ls输出格式,若你的环境输出字段顺序不同,需调整awk中的字段索引(比如$5为文件大小字段,$1为权限字段)
内容的提问来源于stack exchange,提问作者Neo
相关产品推荐
相关产品推荐

