如何用Bash脚本从Dmidecode输出提取指定值?求更优方案
优化从Dmidecode Type 219提取并反转字节的Bash实现
下面提供几种更高效、简洁的实现方式,相比传统多管道组合的脚本,这些方案减少了子进程开销,逻辑更内聚:
方案1:用grep + Perl正则一键提取反转
利用Perl正则的捕获能力和二进制处理特性,一次性完成提取、去空格、字节反转操作:
# 预设要对比的十六进制字符串 TARGET="00000020" # 从dmidecode输出中提取目标数据并处理 result=$(dmidecode -t 219 | grep -oP '(?<=01 85 30 )([0-9A-Fa-f]{2} ){4}' | perl -pe 's/ //g; $_ = reverse unpack("H*", pack("H*", $_))') # 执行对比 if [ "$result" = "$TARGET" ]; then echo "匹配成功" else echo "匹配失败,实际提取值:$result" fi
说明:
grep -oP用Perl正则的正向预查,精准匹配01 85 30后的4个字节- Perl部分先去掉空格,再通过
pack/unpack将十六进制转二进制、反转字节、再转回十六进制,完美实现字节序反转
方案2:用awk全程处理(无额外子进程)
awk可以独立完成定位、提取、反转、对比全流程,避免多次启动外部工具,效率最高:
dmidecode -t 219 | awk -v target="00000020" ' /01 85 30/ { split($0, arr, " ") # 遍历数组找到模式起始位置 for (i=1; i<=length(arr)-5; i++) { if (arr[i]=="01" && arr[i+1]=="85" && arr[i+2]=="30") { # 拼接后4个字节为连续字符串 raw = arr[i+3] arr[i+4] arr[i+5] arr[i+6] # 直接通过字符串截取反转字节序(每2个字符为一个字节) reversed = substr(raw,7,2) substr(raw,5,2) substr(raw,3,2) substr(raw,1,2) # 输出对比结果 print (reversed == target) ? "匹配成功" : "匹配失败,实际值:" reversed exit } } } '
说明:
- 直接在awk内部完成行解析、模式定位、字节反转逻辑,全程仅启动
dmidecode和awk两个进程 - 字节反转通过字符串截取实现,无需依赖二进制处理工具,逻辑直观
方案3:二进制模式下的快速处理(如果能获取DMI二进制数据)
若能直接读取DMI的二进制数据(比如从/sys/firmware/dmi/tables/DMI或用dmidecode --dump-bin导出),可以用xxd配合Perl处理:
TARGET="00000020" # 导出Type219的二进制数据到临时文件 dmidecode -t 219 --dump-bin /tmp/dmi219.bin # 提取反转后对比 result=$(xxd -p /tmp/dmi219.bin | grep -oP '(?<=018530)[0-9A-Fa-f]{8}' | perl -pe '$_ = reverse unpack("H*", pack("H*", $_))') [ "$result" = "$TARGET" ] && echo "匹配成功" || echo "匹配失败:$result" rm /tmp/dmi219.bin
说明:适合需要直接操作二进制DMI表的场景,避免文本解析的潜在误差
内容的提问来源于stack exchange,提问作者embeddedstack
相关产品推荐
相关产品推荐

