解决bash脚本统计.z文件行数时漏计无换行符最后一行的问题
修复.z文件行数统计脚本的问题
问题根源
你的脚本批量处理时统计错误,核心原因有两个:
- 文件内容拼接导致行合并:
xargs zcat会把多个.z文件的内容连续输出,如果前一个文件最后一行没有换行符,会和后一个文件的第一行合并成一行,被awk/wc识别为单行,导致行数统计偏少。 - wc -l的局限性:
wc -l本质是统计输入中的换行符数量,而非实际的行数。当文件最后一行没有换行符时,它不会被计数;单个文件时awk 1会给最后一行补换行,所以统计正确,但批量拼接时无法解决跨文件的行合并问题。
修复后的脚本
todays_day=$(date +%d) if ((todays_day == 1)); then month="$(date --date='1 day ago' +%y%m)" else month="$(date +%y%m)" fi # 处理含特殊字符的目录名,避免拆分 find ./ -type d -name "$month" -print0 | while IFS= read -r -d '' dir; do total_lines=0 # 逐个处理每个.z文件,避免内容拼接 find "$dir" -type f -name "*.z" -print0 | while IFS= read -r -d '' zfile; do # 用awk统计单个文件行数,正确识别无换行的最后一行 file_lines=$(zcat "$zfile" | awk '{count++} END{print count + 0}') total_lines=$((total_lines + file_lines)) done echo "number of lines $total_lines;source $dir;data $(date +"%d-%m-%Y %T")" done
关键改进点
- 逐个文件统计:遍历每个.z文件单独处理,避免跨文件的内容拼接,彻底解决行合并问题。
- 用awk替代wc -l:awk会将每一段被换行分隔的内容(包括最后一段无换行的)视为一行,
{count++}累计行数,END{print count + 0}确保空文件输出0而非空值。 - 处理特殊字符路径:使用
find -print0和read -d ''组合,兼容目录名、文件名含空格、特殊字符的场景,避免原脚本中路径被错误拆分的问题。 - 简化source输出:直接使用已找到的目录路径
$dir,无需重复执行find提升效率。
内容的提问来源于stack exchange,提问作者user20623337
相关产品推荐
相关产品推荐

