我需要解析lsblk
的输出。由于我是在脚本中执行此操作,因此需要以标准格式输出。因此我选择JSON格式作为输出。这是带有一些示例输出的命令:
# lsblk -o NAME,MOUNTPOINT -J
{
"blockdevices": [
{"name": "sda", "mountpoint": null,
"children": [
{"name": "sda1", "mountpoint": "/sda1/mountpoint"},
{"name": "sda2", "mountpoint": null,
"children": [
{"name": "sda2_mapper", "mountpoint": "/sda2/mountpoint"}
]
},
{"name": "sda3", "mountpoint": null},
{"name": "sda4", "mountpoint": null}
]
},
{"name": "sdb", "mountpoint": null,
"children": [
{"name": "sdb1", "mountpoint": "/sdb1/mountpoint"},
{"name": "sdb2", "mountpoint": null}
]
},
{"name": "sdc", "mountpoint": null}
]
}
我想提取所有最里面的节点的名称,即所有没有子节点的节点的名称。上述样本的所需输出为:
sda1
sda2_mapper
sda3
sda4
sdb1
sdb2
sdc
我选择的工具是jq
,我最近才发现。我试过了
# jq '.blockdevices[].children[]?.name?'
但这只会过滤第一级别的名字。我也试过
# jq 'recurse(.name?)'
但这会返回整个文件。
有没有办法只返回没有子节点的节点,无论它们嵌套多深?
PS:我能够在bash
或awk
中实施该要求。但是,我更喜欢使用像jq
这样的工具的解决方案,其具体目的是解析json文件。
答案 0 :(得分:1)
我不认为这是最简单的方法,但似乎有效:
$ jq -r '.blockdevices[] | .. | objects | select(has("children")|not)| .name' tmp.json
sda1
sda2_mapper
sda3
sda4
sdb1
sdb2
sdc
它以递归方式输出JSON中找到的每个值,首先过滤掉任何不是对象的内容,然后过滤掉任何具有children
键的对象。最后,您可以从每个剩余对象中选择name
值。
答案 1 :(得分:0)
使用您的JSON输入,以下命令:
FlaskClient
发出“叶子”,开头:
jq '.. | scalars'
使用-r(原始输出)从字符串中去除引号。