jq-将复杂的JSON解析为字符串

时间:2019-08-13 09:28:15

标签: json parsing jq

我正在尝试使用jq来解析类似于以下内容的JSON:

{
    "username": "billy",
    "hero": {
        "something": "goeshere"
    },
    "bumper": {
        "bumper2": {
            "bumper3": "splodge"
        }
    },
    "morgan": [{
        "abc": 123
    }, 2, 4, {
        "def": 567
    }],
    "password": "issilly"
}

进入

request.username == 'billy' && request.hero.something == 'goeshere' && request.bumper.bumper2.bumper3 == 'splodge' && request.morgan[0].abc == 123 && request.morgan[1] == 2 && request.morgan[2] == 4 && request.morgan[3].def == 567 && request.password == 'issilly'

到目前为止,我必须

jq '. | to_entries[] | "request.\(.key) == '\(.value)'"'

这使我成为其中的一部分,但我无法弄清楚如何“深入”到深层嵌套的元素中,也无法解决如何将生成的字符串连接到以'&&'分隔的单行中>

2 个答案:

答案 0 :(得分:4)

'max.number.of.messages'输出表示paths(scalars)中字符串和数字路径的数组,使用.可以在这些路径中获取值。因此,您所需要的只是一个将路径表示形式转换为路径表达式的函数,例如:

getpath

jqplay上查看

答案 1 :(得分:2)

鉴于JavaScript无法区分foo.barfoo["bar"],这将为您提供与所发布内容完全不同的输出,但应该足够好。

jq -r '
  . as $data |
  [path(.. | 
    select(type != "object" and type != "array")
  )] |
  map(
    . as $path |
    map("[" + (. | tojson) + "]") |
    join("") |
    "request\(.) = \($data | getpath($path) | tojson)"
  ) |
  join(" && ")
' < test.json

输出:

request["username"] = "billy" &&
request["hero"]["something"] = "goeshere" &&
request["bumper"]["bumper2"]["bumper3"] = "splodge" &&
request["morgan"][0]["abc"] = 123 &&
request["morgan"][1] = 2 &&
request["morgan"][2] = 4 &&
request["morgan"][3]["def"] = 567 &&
request["password"] = "issilly"

说明:..为我们提供了所有值;但是我们只需要叶子值,所以我们过滤掉那些是数组或对象的值。然后,我们使用[path()]获得路径数组:这将是路径步骤数组的数组,例如:[["username"], ["hero", "something"], ["bumper", "bumper2", "bumper3"], ["morgan", 0, "abc"]... ]等。现在,对于每个路径,我们都需要将每个路径步骤括在方括号中,以得到一些JavaScript可以理解的东西。 tojson会给出方括号所需的确切内容,以使对象的字符串键被加引号,而数组的整数键则没有。现在,我们可以将等式表达式放在一起:左侧需要在构建的包围式路径之前添加request,而我们可以使用getpath来获取应该在右侧的值(再次)使用tojson来获取正确的文字)。