但仍在努力用jq解析JSON

但仍在努力用jq解析JSON,json,csv,export-to-csv,jq,Json,Csv,Export To Csv,Jq,我正在慢慢掌握jq是如何工作的,但离掌握它还有很长的路要走。 现在我的处境是,我设法得到了我想要的东西,但没有以我想要的方式展示出来。我相信这很简单,但我很想念它 下面是我要解析的JSON示例: { "sites": [ { "site_id": 123456, "status": "configured", "domain": "www.domain.com", "accou

我正在慢慢掌握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"
同样的结果,只显示在一行中。 我翻阅了手册页,摆弄了一会儿也没用。 是否有可能这样做,或者我需要一个不同的工具来操作它


提前谢谢

要在CSV行中打印的所有值必须收集在JSON数组中。因此,与您的尝试非常相似的解决方案是:

.sites[]
| [.site_id, .domain, (.security.waf.rules[] | .action_text) ]
| @csv
顺便说一下,不需要使用
cat

jq -r -f program.jq test.json

首先,让我们讨论一下你为什么会收到这个结果

当您使用
[]
从对象/数组中提取项时,它会为该对象/数组中的每个项生成一个值

.sites[]
站点
数组中的每个值生成一个结果(在本例中只有一个)

另外需要注意的是,使用逗号(
)将在该表达式中生成分隔值

[.site_id,.domain]
这里的逗号产生两个值,
site\u id
。但是,这些值被收集到一个数组中(用方括号表示)

将其放入表达式的下一部分

.security.waf.rules[] | [.action_text]
第一部分介绍该数组中的所有规则对象。然后,为这些对象中的每一个创建一个包含
操作\u文本的数组。这将创建三个数组(每个规则一个)

将其与表达式的前一部分放在一起(稍微重新格式化)

这一共产生了四个数组,一个数组包含
站点id
,然后是
操作文本
的三个数组

然后,对于这四个数组中的每一个,都会创建一个csv行,提供您看到的结果


那么,我们如何才能得到预期的结果呢

首先,我们要开始浏览所有网站。我假设您希望每个站点都有一行

.sites[]
然后,对于每个站点,我们需要在该行中构建一个值数组。从我们可以直接访问的内容开始

.site_id, .domain
然后生成
操作\u文本

.security.waf.rules[].action_text
注意,我们没有将
操作\u文本
放在单独的数组中,我们只需要值

现在我们把这些值放在一起

.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

当然,有很多方法可以获得这些值(比如分别构建数组,然后组合它们),但这是最直接的方法。

Awesome@Jeff Mercado!!!也非常感谢您的详细解释!
.sites[] | [.site_id, .domain, (.security.waf.rules[].action_text)] | @csv