使用awk遍历目录文件计算酒店评分均值的脚本故障排查
解决Shell脚本计算单酒店评论平均分的两个问题
我先理清楚你的场景:你有个reviews_folder目录,里面放着hotel_72572.dat这类单酒店的评论文件,每个文件里有多条评论,每条评论的最后字段应该是总分对吧?你想用averagereviews.sh脚本计算每个酒店的平均评论分,但现在脚本踩了两个典型的Shell坑:一是不认传入的目录参数,二是用hotel_*.dat匹配时会把所有文件的评论攒一起算整体均值,而不是单个酒店单独算。
问题1:无法识别传入的目录
这个问题大概率是脚本没做参数有效性校验,或者路径拼接时没处理好目录的斜杠。比如脚本直接用$1但没检查它是不是真的存在、是不是目录,或者拼接文件路径时没加斜杠,导致变成path_to_reviews_folderhotel_*.dat这种错误路径。
解决思路:
- 先检查用户是否传入了正确数量的参数
- 校验传入的路径是不是有效目录
- 标准化目录路径,避免斜杠拼接错误
问题2:批量文件计算整体均值而非单个文件
这个是因为你可能直接用了cat $dir/hotel_*.dat | awk ...这种写法,把所有文件的内容合并成一个数据流处理了,自然算出来的是所有评论的整体均值。正确的做法是循环遍历每个文件,逐个计算。
解决思路:
- 用
for循环遍历每个hotel_*.dat文件 - 对每个单独的文件执行awk计算逻辑
- 处理空文件或无匹配文件的边界情况
修正后的完整脚本
我把上面的思路整合到脚本里,你可以直接替换原来的averagereviews.sh:
#!/bin/bash # 检查用户是否传入了正确的参数数量 if [ $# -ne 1 ]; then echo "用法: $0 <reviews目录路径>" exit 1 fi reviews_dir="$1" # 校验传入的路径是否为有效目录 if [ ! -d "$reviews_dir" ]; then echo "错误: 传入的路径 '$reviews_dir' 不是一个有效的目录" exit 1 fi # 遍历目录下所有符合格式的酒店评论文件 for hotel_file in "$reviews_dir"/hotel_*.dat; do # 处理没有匹配文件的情况(避免循环执行一次空路径) if [ ! -f "$hotel_file" ]; then echo "警告: 在目录 '$reviews_dir' 中没有找到 hotel_*.dat 格式的文件" break fi # 从文件名中提取酒店ID(比如从hotel_72572.dat中拿到72572) hotel_id=$(basename "$hotel_file" .dat | cut -d'_' -f2) # 计算该酒店的平均评论分:假设每行最后一个字段是总分 # 加入count判断避免空文件除以0的错误 average_score=$(awk '{sum += $NF; count++} END {if(count>0) printf "%.2f", sum/count; else print "0.00"}' "$hotel_file") # 输出清晰的结果 echo "酒店ID $hotel_id 的平均评论分: $average_score" done
脚本关键细节说明:
- 参数校验:确保用户只传一个参数,并且是有效目录,出错时给出明确提示,不会让你一脸懵
- 单个文件循环处理:每个
hotel_*.dat文件单独计算,不会混在一起统计 - 边界处理:如果目录里没有匹配的文件,或者某个文件是空的,脚本会给出提示或输出0分,不会崩溃
- 友好输出:提取酒店ID,并且平均分保留两位小数,结果一目了然
现在你运行./averagereviews.sh path_to_reviews_folder,就能得到每个酒店单独的平均评论分了,再也不会出现目录识别错误或者整体均值的问题。
内容的提问来源于stack exchange,提问作者sj34




