如何通过Bash脚本将Ubuntu命令输出转换为指定JSON格式?
用Bash脚本将Ubuntu命令输出转换为合规JSON的正确方案
核心原则
不要手动拼接JSON字符串——手动处理极易忽略特殊字符(引号、换行、反斜杠)的转义,导致生成的JSON不合规。优先使用jq工具,这是Bash环境下处理JSON的标准工具,Ubuntu可通过apt install jq安装。
示例1:磁盘信息转嵌套JSON
假设我们用lsblk -no NAME,SIZE,TYPE,MOUNTPOINT获取磁盘/分区信息,原始输出如下:
sda 238.5G disk ├─sda1 512M part /boot/efi ├─sda2 1G part /boot └─sda3 236.9G part / sdb 119.2G disk └─sdb1 119.2G part /data
目标是生成包含磁盘和对应分区的嵌套JSON结构,脚本实现如下:
#!/bin/bash # 整理lsblk输出,过滤树形符号后用awk生成JSON骨架,最后用jq校验格式化 lsblk -no NAME,SIZE,TYPE,MOUNTPOINT | grep -vE '^├|^└' | awk ' BEGIN { print "[" } $3 == "disk" { if (disk_started) print "," print "{\"name\":\"" $1 "\",\"size\":\"" $2 "\",\"type\":\"" $3 "\",\"mountpoints\":[" disk_started=1 part_started=0 next } $3 == "part" { if (part_started) print "," print "{\"name\":\"" $1 "\",\"size\":\"" $2 "\",\"mountpoint\":\"" $4 "\"}" part_started=1 } END { print "]}" print "]" }' | jq .
执行后生成的合规JSON:
[ { "name": "sda", "size": "238.5G", "type": "disk", "mountpoints": [ { "name": "sda1", "size": "512M", "mountpoint": "/boot/efi" }, { "name": "sda2", "size": "1G", "mountpoint": "/boot" }, { "name": "sda3", "size": "236.9G", "mountpoint": "/" } ] }, { "name": "sdb", "size": "119.2G", "type": "disk", "mountpoints": [ { "name": "sdb1", "size": "119.2G", "mountpoint": "/data" } ] } ]
示例2:键值对输出转JSON
如果命令输出是key=value格式(比如systemctl show的输出),提取sshd的部分状态:
Type=notify Restart=always PIDMain=1234 ExecStart=/usr/sbin/sshd -D $OPTIONS
用jq直接处理的简洁脚本:
systemctl show sshd -p Type,Restart,PIDMain,ExecStart --value | jq -R ' split("\n") | map(split("=")) | reduce .[] as $arr ({}; if $arr | length == 2 then .[$arr[0]] = $arr[1] else . end )'
生成的JSON:
{ "Type": "notify", "Restart": "always", "PIDMain": "1234", "ExecStart": "/usr/sbin/sshd -D $OPTIONS" }
关键注意事项
- 强制用jq校验格式化:哪怕用脚本拼接完JSON,最后通过
jq .管道处理,既能格式化输出,也能自动修复转义问题,确保JSON合规。 - 处理空值/特殊字符:如果输出字段可能为空(比如未挂载的分区),jq会自动处理空字符串,避免JSON语法错误。
- 避免硬编码拼接:对于复杂结构,先用awk/sed整理成每行一个JSON片段,再用jq合并,比纯手动拼接可靠得多。
内容的提问来源于stack exchange,提问作者Devil
相关产品推荐
相关产品推荐

