我正在慢慢掌握jq如何工作,但我还远未掌握它。 现在我处于一种情况,我有点想要得到我想要的东西,但不是按照我想要的方式展示它。我确信这很简单,但我很想念......
以下是我要解析的JSON示例:
{
"sites": [
{
"site_id": 123456,
"status": "configured",
"domain": "www.domain.com",
"account_id": 654321,
"security": {
"waf": {
"rules": [
{
"action": "block_request",
"action_text": "Block",
"id": "sqli",
"name": "SQLi"
},
{
"action": "block_request",
"action_text": "Block",
"id": "xss",
"name": "XSS"
},
{
"action": "alert",
"action_text": "Alert",
"id": "path_vector",
"name": "Path Vector"
}
]
}
}
}
],
"res": 0,
"res_message": "OK",
"debug_info": {
"id-info": "9123"
}
}
我只需要一些细节并将它们放在CSV格式中,这是我到目前为止所做的:
cat test.json | jq -r '.sites [] | [.site_id,.domain],(.security.waf.rules[] | [.action_text]) | @csv'
这是我得到的输出:
123456,"www.domain.com"
"Block"
"Block"
"Alert"
不是那么糟糕,但我正在寻找的是这样的:
123456,"www.domain.com","Block","Block","Alert"
相同的结果,只显示在一行中。 我走过手册页,摆弄了一会儿无济于事。 是可以这样做还是我需要一个不同的工具来操纵它?
提前致谢!
答案 0 :(得分:4)
首先让我们讨论一下你收到这个结果的原因。
当您使用[]
从对象/数组中提取项目时,它会为该对象/数组中的每个项目生成一个值。
.sites[]
为sites
数组中的每个值生成一个结果(在这种情况下只有一个)。
另外需要注意的是,使用逗号(,
)将在该表达式中生成分隔值。
[.site_id,.domain]
此处的逗号会生成两个值,site_id
和domain
。但是,这些值被收集到一个数组中(如方括号所示)。
将其放入表达式的下一部分
.security.waf.rules[] | [.action_text]
第一部分遍历该数组中的所有规则对象。然后,对于每个对象,创建一个包含action_text
的数组。这将创建三个数组(每个规则一个)。
将它与表达式的前一部分(稍微重新格式化)放在一起
([.site_id,.domain]) , (.security.waf.rules[] | [.action_text])
这一切共同产生四个数组,该数组包含site_id
和domain
,后跟三个action_text
数组。
然后,对于这四个数组中的每一个,都会创建一个csv行,为您提供所见的结果。
那么我们怎样才能得到理想的结果?
首先,我们要开始浏览所有网站。我假设你想要每个站点一行。
.sites[]
然后,对于每个站点,我们需要在该行中构建值的数组。从我们可以直接访问的内容开始。
.site_id, .domain
然后生成action_text
值。
.security.waf.rules[].action_text
注意我们没有将action_text
放在一个单独的数组中,我们只想要这个值。
现在我们将这些值放在一起。
.site_id, .domain, (.security.waf.rules[].action_text)
这会在我们讨论的情况下创建五个值,但我们希望在数组中收集这些值,以便我们将其传递给@csv
过滤器。
[.site_id, .domain, (.security.waf.rules[].action_text)]
将所有内容放在一起将为我们提供此过滤器:
.sites[] | [.site_id, .domain, (.security.waf.rules[].action_text)] | @csv
当然,您可以采用许多方法来获取这些值(例如分别构建数组然后组合它们),但这是最直接的。
答案 1 :(得分:3)
必须在JSON数组中收集要在CSV行中打印的所有值。因此,与您的尝试非常相似的解决方案是:
.sites[]
| [.site_id, .domain, (.security.waf.rules[] | .action_text) ]
| @csv
顺便说一句,没有必要使用cat
:
jq -r -f program.jq test.json