Shell脚本对比YES/NO答案双文件,统计好坏答案数并存独立变量实现
Shell逐行对比文件的变量存储实现方案
实现目标
- 接收两个文件作为脚本入参
- 逐行对比两个文件内的YES/NO答案内容
- 将匹配一致的正确答案数、不匹配的错误答案数分别存储为独立Shell变量,供后续逻辑调用
- 解决原diff命令执行后无法将统计结果存入变量的问题
高可靠性逐行对比实现
不依赖外部命令输出格式,兼容所有POSIX标准Shell环境,代码如下:
#!/bin/bash # 入参校验 if [[ $# -ne 2 ]]; then echo "脚本用法:$0 <答案文件1路径> <答案文件2路径>" exit 1 fi # 初始化两个独立统计变量 match_count=0 # 存储匹配一致的正确答案数量 mismatch_count=0 # 存储不匹配的错误答案数量 # 逐行并行读取两个文件完成对比 while IFS= read -r line1 && IFS= read -r line2 <&3; do # 清除所有空白字符做归一化,避免因多打空格/缩进误判结果 norm_line1=$(printf "%s" "$line1" | tr -d '[:space:]') norm_line2=$(printf "%s" "$line2" | tr -d '[:space:]') # 对比结果累加计数 if [[ "$norm_line1" == "$norm_line2" ]]; then ((match_count++)) else ((mismatch_count++)) fi done < "$1" 3< "$2" # 运行验证输出 echo "匹配一致数量:$match_count" echo "不匹配错误数量:$mismatch_count"
沿用原diff思路的正确变量存储写法
之前的命令无法存入变量,核心问题是没有使用命令替换语法捕获执行输出,且原逻辑存在格式误判的缺陷。修正后的可直接赋值的写法:
# 统计不匹配的错误数量,存入mismatch_count变量 mismatch_count=$(diff <(cat -A "$1") <(cat -A "$2") | grep -c '^<') # 用总有效行数减去错误数得到匹配数,存入match_count变量 total_lines=$(wc -l < "$1") match_count=$(( total_lines - mismatch_count ))
优化说明:
- 用
cat -A替代原命令中的nl,可以显式标记行尾隐藏字符、换行差异,避免diff把纯格式问题当成内容不匹配- 用
grep -c直接输出匹配到的行数,不需要额外管道传给wc -l,减少不必要的进程开销- 用
$(...)命令替换包裹整条统计命令,输出结果直接赋值给外层变量,不会出现子shell赋值失效的问题
常见踩坑点
- 不要将变量赋值操作放在管道链路的最后一段:管道中的命令运行在独立子shell中,赋值的变量不会被外层脚本读取到,这是Shell环境下变量捕获失败的最常见原因
- 对比YES/NO这类简单答案时,一定要做内容归一化处理,清除所有冗余空白,否则输入时多打一个空格就会被误判为错误答案
内容的提问来源于stack exchange,提问作者Daniel Jeleń Morzejko
相关产品推荐
相关产品推荐

