求助:Bash内存日志转换脚本仅输出时间,内存字段为空
问题排查:Bash脚本内存日志转换错误
问题场景
需要将包含时间和内存统计的日志文件转换为逗号分隔的CSV格式,但执行编写的Bash脚本后,仅输出时间字段,内存相关字段均为空。
错误原因分析
read命令语法错误
原脚本中while read -a LINE from $FILE是错误写法,read命令不需要from关键字,正确的读取方式是通过循环末尾的重定向done < $FILE来指定输入文件,循环内只需保留read -a LINE。Case匹配字符串不匹配
日志中内存相关行的第一个字段是MemTotal:、MemFree:、MemAvailable:(末尾带有冒号),但脚本的case分支匹配的是不带冒号的"MemTotal"、"MemFree"、"MemAvailable",导致这些行无法匹配到对应的赋值分支,内存变量始终未被赋值。输出时机错误
原脚本每读取一行就立即拼接并输出LINEOUT,但时间行读取时,内存字段还未从后续行获取到值,此时输出会得到空的内存字段;而内存行读取时又会重复输出带当前时间的行,导致冗余输出。
修正后的脚本
#!/bin/bash set -x TIME="" MEMTOTAL="" MEMFREE="" MEMAVAIL="" FILE="./SMALL-SAMPLE.txt" # 定义输出函数,仅当所有字段都赋值完成时输出 output_line() { if [[ -n "$TIME" && -n "$MEMTOTAL" && -n "$MEMFREE" && -n "$MEMAVAIL" ]]; then echo "$TIME,$MEMTOTAL,$MEMFREE,$MEMAVAIL" # 重置变量,准备下一组数据 TIME="" MEMTOTAL="" MEMFREE="" MEMAVAIL="" fi } while read -a LINE do WORD1=${LINE[0]} case "$WORD1" in "Fri") # 读取到新时间时,先输出上一组完整数据 output_line TIME=${LINE[3]} ;; "MemTotal:") MEMTOTAL=${LINE[1]} ;; "MemFree:") MEMFREE=${LINE[1]} ;; "MemAvailable:") MEMAVAIL=${LINE[1]} ;; *) continue ;; esac done < "$FILE" # 输出最后一组未处理的数据 output_line
修正逻辑说明
- 修正
read命令的语法错误,移除多余的from $FILE - Case分支匹配带冒号的字段,确保内存行能正确触发赋值逻辑
- 添加
output_line函数,仅当时间和所有内存字段都完成赋值时才输出CSV行,避免空字段;读取到新时间时先输出上一组数据,循环结束后再输出最后一组数据,保证数据完整性。
内容的提问来源于stack exchange,提问作者tbh
相关产品推荐
相关产品推荐

