Bash循环中变量比较结果异常导致输出不符的问题求解
问题原因分析
- 核心错误:你的
test文件末尾缺少换行符,触发了read命令的经典坑。while read循环只有在读取到带换行符的行时才会返回0执行循环体,如果最后一行没有结尾换行符,read会把内容加载到变量但返回非0退出码,直接跳过这一行。所以内层循环根本没读取到test里的f3行,自然匹配失败,误判f3是新增元素。 - 次要问题1:打印数组时用了
${added[*]},这个语法会把所有数组元素用空格拼接成单个字符串输出,和你预期的逐行输出逻辑不符。 - 次要问题2:脚本开头的shebang多写了一个
#,虽然用bash 脚本名运行不受影响,但直接执行脚本时可能导致系统识别解释器失败。 - 不规范点:数字比较用
==属于字符串比较逻辑,用整数比较符-eq更稳妥,变量不加引号在字段含特殊字符时可能报错。
修复后的脚本
#!/bin/bash added=() # 新增|| [ -n "$变量" ]逻辑,兼容无换行的最后一行 while read F_NEW O_NEW G_NEW P_NEW || [ -n "$F_NEW" ]; do exist=0 while read F O G P || [ -n "$F" ]; do # 同时存在于新旧文件 if [[ "$F_NEW" == "$F" ]]; then exist=1 break fi done < test if [[ $exist -eq 0 ]]; then echo "$F_NEW" added+=("$F_NEW") fi done < test_new # 用@代替*逐行输出数组元素 printf '%s\n' "${added[@]}"
高效替代方案
如果处理的文件体积较大,双层循环效率很低,可以直接用awk一行实现需求:
awk 'NR==FNR {old[$1]++; next} !old[$1] {print $1}' test test_new
内容的提问来源于stack exchange,提问作者kittygirl
相关产品推荐
相关产品推荐

