将 JSON 个对象传递给 jq 参数
Passing JSON objects to jq arguments
数据样本 - sample.json(完整样本:https://pastebin.com/KFkVmc2M)
{
"ip": 3301234701,
"_shodan": {
"options": {
"referrer": "7ae15507-f5cc-4353-b72e-5cc0b1c34c5e"
},
},
"hash": -1056085507,
"os": null,
"title": "WHM Login",
"opts": {
"vulns": ["!CVE-2014-0160"],
"heartbleed": "2017/08/29 09:57:30 196.196.216.13:2087 - SAFE\
}
},
"isp": "Fiber Grid Inc",
"http": {
"redirects": [],
"title": "WHM Login",
"robots": null,
"favicon": null,
"host": "196.196.216.13",
"html":
}
我希望使用 jq 的脚本可以工作,但尚未找到其他解决方案。
cat sample.json | jq \
--arg key0 'Host' \
--arg value0 '.host' \
--arg key1 'Vulnerability' \
--arg value1 '.opts.vulns[0]' \
--arg key2 'ISP' \
--arg value2 '.isp' \
'. | .[$key0]= $value0 | .[$key1]=$value1 | .[$key2]=$value2' \
<<<'{}'
我希望但没有得到的最终结果:
{
"Host": "196.196.216.13",
"Vulnerability": "!CVE-2014-0160",
"ISP": "Fiber Grid Inc"
}
现在它只是 returns 作为字符串的对象,我已经尝试了很多不同的方法来解决这个问题。我对使用 JSON 和 jq 还很陌生,但根据我目前所读的内容,解决方案可能不像我希望的那么简单?
简而言之,为什么对象没有作为 sample.json 对象的值返回,我必须做什么才能让它工作?
谢谢!
致:切普纳
{
"196.196.216.13":[
"AS63119",
"Fiber Grid Inc",
"2017-08-29T06:57:22.546423",
"!CVE-2014-0160"
],
"196.196.216.14":[
"AS63119",
"Fiber Grid Inc",
"2017-08-29T06:57:22.546423",
"!CVE-2014-0160"
]
}
jq 不支持在
您尝试工作所需的方式。你可以做一些
一种 shell 插值,但最好使用 JSON 路径,
例如而不是 --arg value0 .host
,你可以写 --arg value0 "host"
,等等。在下面,我使用了 getpath/1
.
不需要在 jq 过滤器前加上 '. |'
无论如何,假设 pastebin 的 JSON 内容在 pastebin.json 中,您可以这样写:
jq \
--arg key0 Host \
--argjson value0 '["http","host"]' \
--arg key1 Vulnerability \
--argjson value1 '["opts", "vulns", 0]' \
--arg key2 ISP \
--argjson value2 '["isp"]' \
'. as $in
| {}
| .[$key0] = ($in|getpath($value0))
| .[$key1] = ($in|getpath($value1))
| .[$key2] = ($in|getpath($value2))' \
pastebin.json
这会得到结果:
{
"Host": "196.196.216.13",
"Vulnerability": "!CVE-2014-0160",
"ISP": "Fiber Grid Inc"
}
这是使用@CharlesDuffy 建议的方法的变体解决方案:
$ config='{"Host": ["http", "host"],
"Vulnerability": ["opts", "vulns", 0],
"ISP": ["isp"]}'
$ jq --argjson config "$config" '
. as $in
| $config
| map_values( . as $p | $in | getpath($p) )' pastebin.json
输出:
{
"Host": "196.196.216.13",
"Vulnerability": "!CVE-2014-0160",
"ISP": "Fiber Grid Inc"
}
这顺便强调了@chepner 的观点:$config 所需的保养和维护不亚于相应的 jq 查询所需的保养和维护,而 jq 查询语言——在设计上——提供了更多的灵活性.
回复补充问题("to: chepner"):
pastebin 数据不包含“196.196.216.14”,因此补充问题不清楚,但您可能希望从以下内容开始:
jq '{(.ip_str): [.asn, .isp, .timestamp, opts.vulns[0] ]}' pastebin.json
这会产生:
{
"196.196.216.13": [
"AS63119",
"Fiber Grid Inc",
"2017-08-29T06:57:22.546423",
"!CVE-2014-0160"
]
}
这里的重点是 .ip_str
.
两边的一对括号
如其他地方所述,jq 查询再次如此简单明了,以至于参数化版本是否会提供任何优势似乎值得怀疑。
数据样本 - sample.json(完整样本:https://pastebin.com/KFkVmc2M)
{
"ip": 3301234701,
"_shodan": {
"options": {
"referrer": "7ae15507-f5cc-4353-b72e-5cc0b1c34c5e"
},
},
"hash": -1056085507,
"os": null,
"title": "WHM Login",
"opts": {
"vulns": ["!CVE-2014-0160"],
"heartbleed": "2017/08/29 09:57:30 196.196.216.13:2087 - SAFE\
}
},
"isp": "Fiber Grid Inc",
"http": {
"redirects": [],
"title": "WHM Login",
"robots": null,
"favicon": null,
"host": "196.196.216.13",
"html":
}
我希望使用 jq 的脚本可以工作,但尚未找到其他解决方案。
cat sample.json | jq \
--arg key0 'Host' \
--arg value0 '.host' \
--arg key1 'Vulnerability' \
--arg value1 '.opts.vulns[0]' \
--arg key2 'ISP' \
--arg value2 '.isp' \
'. | .[$key0]= $value0 | .[$key1]=$value1 | .[$key2]=$value2' \
<<<'{}'
我希望但没有得到的最终结果:
{
"Host": "196.196.216.13",
"Vulnerability": "!CVE-2014-0160",
"ISP": "Fiber Grid Inc"
}
现在它只是 returns 作为字符串的对象,我已经尝试了很多不同的方法来解决这个问题。我对使用 JSON 和 jq 还很陌生,但根据我目前所读的内容,解决方案可能不像我希望的那么简单?
简而言之,为什么对象没有作为 sample.json 对象的值返回,我必须做什么才能让它工作?
谢谢!
致:切普纳
{
"196.196.216.13":[
"AS63119",
"Fiber Grid Inc",
"2017-08-29T06:57:22.546423",
"!CVE-2014-0160"
],
"196.196.216.14":[
"AS63119",
"Fiber Grid Inc",
"2017-08-29T06:57:22.546423",
"!CVE-2014-0160"
]
}
jq 不支持在 您尝试工作所需的方式。你可以做一些 一种 shell 插值,但最好使用 JSON 路径, 例如而不是
--arg value0 .host
,你可以写--arg value0 "host"
,等等。在下面,我使用了getpath/1
.不需要在 jq 过滤器前加上 '. |'
无论如何,假设 pastebin 的 JSON 内容在 pastebin.json 中,您可以这样写:
jq \
--arg key0 Host \
--argjson value0 '["http","host"]' \
--arg key1 Vulnerability \
--argjson value1 '["opts", "vulns", 0]' \
--arg key2 ISP \
--argjson value2 '["isp"]' \
'. as $in
| {}
| .[$key0] = ($in|getpath($value0))
| .[$key1] = ($in|getpath($value1))
| .[$key2] = ($in|getpath($value2))' \
pastebin.json
这会得到结果:
{
"Host": "196.196.216.13",
"Vulnerability": "!CVE-2014-0160",
"ISP": "Fiber Grid Inc"
}
这是使用@CharlesDuffy 建议的方法的变体解决方案:
$ config='{"Host": ["http", "host"],
"Vulnerability": ["opts", "vulns", 0],
"ISP": ["isp"]}'
$ jq --argjson config "$config" '
. as $in
| $config
| map_values( . as $p | $in | getpath($p) )' pastebin.json
输出:
{
"Host": "196.196.216.13",
"Vulnerability": "!CVE-2014-0160",
"ISP": "Fiber Grid Inc"
}
这顺便强调了@chepner 的观点:$config 所需的保养和维护不亚于相应的 jq 查询所需的保养和维护,而 jq 查询语言——在设计上——提供了更多的灵活性.
回复补充问题("to: chepner"):
pastebin 数据不包含“196.196.216.14”,因此补充问题不清楚,但您可能希望从以下内容开始:
jq '{(.ip_str): [.asn, .isp, .timestamp, opts.vulns[0] ]}' pastebin.json
这会产生:
{
"196.196.216.13": [
"AS63119",
"Fiber Grid Inc",
"2017-08-29T06:57:22.546423",
"!CVE-2014-0160"
]
}
这里的重点是 .ip_str
.
如其他地方所述,jq 查询再次如此简单明了,以至于参数化版本是否会提供任何优势似乎值得怀疑。