Bash脚本while循环遍历告警文件每次迭代输出变量异常求助
问题原因
- 核心错误:循环内的
grep命令每次都读取完整的critical文件,而非当前循环读到的单条行内容$line,导致每次循环都会返回全文件所有匹配结果,文件有多少行就重复输出多少次全量匹配值。 - 次要问题:正则表达式中OID的
.未转义,.在正则中默认匹配任意字符,存在匹配错误的风险。 - 冗余问题:逐行读+循环内反复调用grep的写法效率极低,大文件场景下性能会非常差。
修复方案
方案1:最小改动原脚本
仅修改匹配逻辑为处理当前单行内容,保留你原有的代码结构:
# 先清空输出文件,避免重复追加 > critical_body while read line do s=`echo "$line" | grep -Po '(?<=sender:).*' | cut -d ',' -f1` t=`echo "$line" | grep -Po '(?<=time:).*' | cut -d '.' -f1` d=`echo "$line" | grep -Po '(?<=\.1\.3\.6\.1\.4\.1\.2285\.1\.1\.8:).*' | cut -d ',' -f1` echo "Sender: $s" >> critical_body echo "Time: $t" >> critical_body echo "Description: $d" >> critical_body # 每条告警之间加空行分隔 echo "" >> critical_body done < critical
方案2:高效awk单命令方案(推荐)
无需循环,一次遍历文件完成所有处理,性能远高于循环调用grep的写法:
awk ' { # 提取sender字段 match($0, /sender: ([^,]+)/, arr) s=arr[1] # 提取time字段,过滤小数点后冗余内容 match($0, /time: ([0-9\/ :]+)\./, arr) t=arr[1] # 提取指定OID对应的描述字段 match($0, /\.1\.3\.6\.1\.4\.1\.2285\.1\.1\.8:([^,]+)/, arr) d=arr[1] # 按要求输出格式打印 print "Sender: "s print "Time: "t print "Description: "d print "" }' critical > critical_body
两种方案输出结果都和你期望的格式完全一致。
内容的提问来源于stack exchange,提问作者Stacker123
相关产品推荐
相关产品推荐

