然而努力用jq解析JSON [英] Yet struggling to parse JSON with jq

查看:139
本文介绍了然而努力用jq解析JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我逐渐了解jq的工作原理,但还远远不能掌握它. 现在,我处于某种情况下设法获得了想要的东西,但没有按照我想要的方式显示它.我敢肯定这很简单,但是我很想念...

I'm slowly getting a grip of how jq works but am still far from mastering it. Now I'm in a situation I've kinda managed to get what I wanted but not to display it the way I want. I'm sure it's quite simple but I'm missing it...

这是我要解析的JSON示例:

Here's a sample of the JSON I want to parse:

{
    "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格式输入,这是我到目前为止所做的:

I only need a few details and put them in CSV format, here's what I did so far:

cat test.json | jq -r '.sites [] | [.site_id,.domain],(.security.waf.rules[] | [.action_text]) | @csv'

这是我得到的输出:

123456,"www.domain.com"
"Block"
"Block"
"Alert"

还不错,但是我正在寻找的东西是这样的:

Not so bad, but what I'm looking for is something like this:

123456,"www.domain.com","Block","Block","Alert"

相同的结果,仅显示在一行中. 我翻阅了手册页,摆弄了一会儿无济于事. 有可能做到这一点,还是我需要其他工具来操纵它?

Same result, just displayed in one single line. I went over the man pages and fiddled around for a while to no avail. Is it possible to do it or I need a different tool to manipulate it?

提前谢谢!

推荐答案

首先让我们讨论一下为什么收到此结果.

First lets discuss why you received that result.

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

When you use [] to extract items from objects/arrays, it yields a value for every item in that object/array.

.sites[]

sites数组中的每个值生成一个结果(在这种情况下,只有一个).

produces a result for the every value in your sites array (which in this case there's only one).

另外要注意的是,使用逗号(,)将在该表达式中产生定界的值.

Another thing to note, using a comma (,) will yield the delimited values within that expression.

[.site_id,.domain]

此处的逗号产生两个值,site_iddomain.但是,这些值被收集到一个数组中(如方括号所示).

The comma here produces two values, the site_id and the domain. But, those values are collected in to an array (as denoted by the square brackets).

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

Putting this into the next part of the expression

.security.waf.rules[] | [.action_text]

第一部分遍历该数组中的所有规则对象.然后为每个对象创建一个包含action_text的数组.这将创建三个数组(每个规则一个).

The first part goes through all the rules objects in that array. Then for each of those objects, creates an array containing the action_text. This creates three arrays (one for each of the rules).

将此内容与表达式的前半部分(略微重新格式化)

Put this together with the previous part of the expression (slightly reformatted)

([.site_id,.domain]) , (.security.waf.rules[] | [.action_text])

所有这些共同产生四个数组,该数组包含site_iddomain,然后是三个action_text数组.

This all together produces four arrays, the array containing the site_id and domain, followed by the three arrays of action_text.

然后为这四个数组中的每个数组创建一个csv行,为您提供看到的结果.

Then for each of those four arrays, a csv row is created giving you the results you see.

那我们怎样才能得到想要的结果?

So how can we get the desired results?

首先,我们要开始浏览所有站点.我假设您要每个站点一行.

First, we'll want to start go through all the sites. I'm assuming you want a row per site.

.sites[]

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

Then for each site, we need to build an array of the values in that row. Start with what we have direct access to.

.site_id, .domain

然后产生action_text值.

.security.waf.rules[].action_text

请注意,我们没有将action_text放在单独的数组中,我们只需要该值.

Note we're not putting the action_text in a separate array, we just want the value.

现在,我们将这些值放在一起.

Now we put those values together.

.site_id, .domain, (.security.waf.rules[].action_text)

如我们所讨论的,这将创建五个值,但是我们希望将它们收集到一个数组中,以便可以将其传递给@csv过滤器.

This creates five values as we discussed, but we want to collect them in an array so we may pass it to the @csv filter.

[.site_id, .domain, (.security.waf.rules[].action_text)]

将所有内容放在一起将为我们提供此过滤器:

Putting everything together will give us this filter:

.sites[] | [.site_id, .domain, (.security.waf.rules[].action_text)] | @csv

当然,您可以采用多种方法来获取这些值(例如分别构建数组然后组合它们),但这是最直接的.

Of course there's many approaches you can take to get these values (like building out arrays separately then combining them) but this is the most direct.

这篇关于然而努力用jq解析JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆