Return key/value 对 jq
Return key/value pairs in jq
我有以下 json 输出(由 ansible 生成)和一个看似简单的任务,即用 jq
拉出一些 key/value 对。但是,我似乎无法获得我想要的输出。
{
"custom_stats": {},
"plays": [
{
"play": {
"id": "001dd8b7-1cca-07c6-2280-00000000043a",
"name": "Ansible Ad-Hoc"
},
"tasks": [
{
"hosts": {
"hostname01-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname02-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname03-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname04-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname05-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname06-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname07-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname01-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname02-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname03-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname04-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname05-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname01-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname02-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname03-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname04-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname05-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname06-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname07-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
}
},
"task": {
"id": "001dd8b7-1cca-07c6-2280-00000000043c",
"name": "debug"
}
}
]
}
],
"stats": {
"hostname01-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname02-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname03-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname04-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname05-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname06-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname07-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname01-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname02-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname03-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname04-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname05-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname01-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname02-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname03-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname04-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname05-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname06-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname07-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
}
}
}
基本上,我只希望在同一行返回最内层对象的键及其 hw_system_serial
的值。像这样:
hostname01-con: <SERIAL_NUMBER_1>
hostname02-con: <SERIAL_NUMBER_2>
etc
我觉得这应该是微不足道的(我本可以在这段时间写一些 ruby 或 python 脚本......),但我可能无法尝试正确的。我已经尝试了各种各样的事情,但我最终要么遍历 每个 序列号的主机列表,要么返回两个单独的列表(一个主机和一个序列号)。
例如,这个:
.plays[].tasks[].hosts | keys as $hosts | .[].hw_system_serial as $serial | $hosts | join(": ") + $serial
returns 单行中每个主机名的列表,后跟一个序列号。
我 认为 如果我可以将 $serial
转换为数组,它会起作用,但我尝试使用 split()
也失败了(例如 $serial | split("\r")
returns 单项数组列表而不是项目数组)。
我在这里错过了什么?我觉得 jq
应该很容易处理这个(同样,任何带有 JSON 解析器的脚本语言......),但它不是完成这项工作的正确工具吗?
是的,这对 jq
工具是可行的:
jq -r '.plays[].tasks[].hosts | to_entries[] | "\(.key +": "+ .value.hw_system_serial)"' input.json
输出:
hostname01-con: <SERIALNUMBER>
hostname02-con: <SERIALNUMBER>
hostname03-con: <SERIALNUMBER>
hostname04-con: <SERIALNUMBER>
hostname05-con: <SERIALNUMBER>
hostname06-con: <SERIALNUMBER>
hostname07-con: <SERIALNUMBER>
我有以下 json 输出(由 ansible 生成)和一个看似简单的任务,即用 jq
拉出一些 key/value 对。但是,我似乎无法获得我想要的输出。
{
"custom_stats": {},
"plays": [
{
"play": {
"id": "001dd8b7-1cca-07c6-2280-00000000043a",
"name": "Ansible Ad-Hoc"
},
"tasks": [
{
"hosts": {
"hostname01-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname02-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname03-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname04-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname05-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname06-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname07-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname01-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname02-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname03-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname04-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname05-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname01-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname02-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname03-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname04-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname05-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname06-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
},
"hostname07-con": {
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"action": "debug",
"changed": false,
"hw_system_serial": "<SERIALNUMBER>"
}
},
"task": {
"id": "001dd8b7-1cca-07c6-2280-00000000043c",
"name": "debug"
}
}
]
}
],
"stats": {
"hostname01-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname02-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname03-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname04-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname05-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname06-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname07-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname01-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname02-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname03-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname04-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname05-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname01-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname02-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname03-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname04-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname05-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname06-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
},
"hostname07-con": {
"changed": 0,
"failures": 0,
"ok": 1,
"skipped": 0,
"unreachable": 0
}
}
}
基本上,我只希望在同一行返回最内层对象的键及其 hw_system_serial
的值。像这样:
hostname01-con: <SERIAL_NUMBER_1>
hostname02-con: <SERIAL_NUMBER_2>
etc
我觉得这应该是微不足道的(我本可以在这段时间写一些 ruby 或 python 脚本......),但我可能无法尝试正确的。我已经尝试了各种各样的事情,但我最终要么遍历 每个 序列号的主机列表,要么返回两个单独的列表(一个主机和一个序列号)。
例如,这个:
.plays[].tasks[].hosts | keys as $hosts | .[].hw_system_serial as $serial | $hosts | join(": ") + $serial
returns 单行中每个主机名的列表,后跟一个序列号。
我 认为 如果我可以将 $serial
转换为数组,它会起作用,但我尝试使用 split()
也失败了(例如 $serial | split("\r")
returns 单项数组列表而不是项目数组)。
我在这里错过了什么?我觉得 jq
应该很容易处理这个(同样,任何带有 JSON 解析器的脚本语言......),但它不是完成这项工作的正确工具吗?
是的,这对 jq
工具是可行的:
jq -r '.plays[].tasks[].hosts | to_entries[] | "\(.key +": "+ .value.hw_system_serial)"' input.json
输出:
hostname01-con: <SERIALNUMBER>
hostname02-con: <SERIALNUMBER>
hostname03-con: <SERIALNUMBER>
hostname04-con: <SERIALNUMBER>
hostname05-con: <SERIALNUMBER>
hostname06-con: <SERIALNUMBER>
hostname07-con: <SERIALNUMBER>