shell 用JQ解析对象数组

yebdmbv4  于 12个月前  发布在  Shell
关注(0)|答案(2)|浏览(161)

我调用了一个curl请求,并以JSON对象数组的形式接收数据。我想使用这个JSON对象数组作为其他JSON中的值。第二个JSON将作为API调用的请求体发送。
从curl请求收到的响应

[
    {
        id:1,
        "term":"term1"
    },
    {
        id:2,
        "term":"term2"
    },
    {
        id:3,
        "term":"term3"
    }
]

我在jq的帮助下构造了新的JSON,并将JSON数组解析为--arg。因此,由于这个原因,数组被解析为字符串,所以我的问题是,我如何在JSON中传递数组,以便它不会获得转义字符,即。不会被解析为字符串。

6ojccjat

6ojccjat1#

你可以使用jq来转换小的准JSON文本,如图所示,将其视为一个程序,例如:沿着下列路线:

function text {
    cat<<EOF
[
    {
        id:1,
        "term":"term1"
    },
    {
        id:2,
        "term":"term2"
    },
    {
        id:3,
        "term":"term3"
    }
]
EOF
}

jq -n -f <(text)
fiei3ece

fiei3ece2#

jq通常只能将JSON编码的数据解析为JSON,如果它是有效的JSON。这就是jq从STDIN、输入文件或使用--argjson--jsonargs--argfile--slurpfile选项时读取的方式。如果你的输入最初被解释为原始字符串数据(通过使用--raw-input--rawfile--arg--args选项),你仍然可以在JSON编码的字符串上使用jq代码中的fromjson过滤器来解析它们,但仍然需要有效的编码。
如果你的输入数据不是有效的JSON(参见https://www.json.org/获取完整的规范),你的选择取决于它与JSON的区别。以下是其中的一些:

  • jq有许多内置函数来处理字符串数据,因此您可以编写任何东西,从解决特定格式冲突的JSON转换器到为您的整体目标量身定制的完整解释器。当然,这对任何有能力的编程语言都是正确的,我只是想指出jq确实是其中之一,如果你已经有了jq代码来处理你的输入,它实际上是一个合理的选择。
  • jq语言本身是JSON的超集,您的示例数据恰好是有效的jq代码。因此,您可以使用jq将数据解释为代码,尽管在处理未知输入数据时,尤其是在生产环境中,这通常被认为是不好的做法。参见@peak的answer示例。
  • YAML也是JSON的超集,并且您的示例数据也恰好是有效的YAML数据(因此您可以使用任何YAML解释器来至少解析输入),但在这种情况下,id:1的措辞不会被解释为键id下的值1,而是键id:1下的未定义值。(如果在id:1之间有一个空间,那么它会。尽管如此,您仍然可以尝试使用一个工具,将YAML转换为JSON,或者直接以您想要的方式处理YAML(几乎有效)JSON输入,并使用id:1解决问题。尽管付出了更多的努力,但总的来说,这仍然是更好的实践,因为YAML数据仍然被视为数据,而不是代码。
  • yq(kislyuk的实现)是一个构建在jq之上的YAML处理器。它将YAML输入转换为JSON,然后调用jq来处理它。这种解决方案的优点是您可以不受限制地使用您的原始jq代码。以下是如何修复id:1问题(如果值应该保持为字符串,则删除| tonumber):
yq 'map(with_entries(
  select(.key | startswith("id:")) |= {key: "id", value: (.key[3:] | tonumber)}
))' invalid.json
  • gojq是对Go语言中的jq的重写,增加了一些额外的功能,包括一个可以使用--yaml-input选项激活的YAML解释器。它的语言与jq的语言几乎相同(尽管存在一些微小的差异),因此可以应用相同的修复方法,并且实际上可以利用该解决方案的相同优势。
gojq --yaml-input 'map(with_entries(
  select(.key | startswith("id:")) |= {key: "id", value: (.key[3:] | tonumber)}
))' invalid.json
  • yq(mikefarah的实现)是另一个YAML处理器,它以jq为基础构建,但又独立于jq。因此,它们的语言在设计上有许多相似之处,但并不总是可以互换的。因此,使用这个解决方案,修复有些不同(如果值应该保持为字符串,则删除| . tag = "!!int"),并且重用原始jq代码也可能受到限制。
yq -py -oj 'map(
  ."id:*" |= (key | sub("...", "") | . tag = "!!int" | key = "id")
)' invalid.json
  • Hjson是JSON的语法扩展。它将自己描述为“人类的用户界面,在将JSON数据传递给机器之前进行读取和编辑”。因此,它允许JSON不允许的功能(如注解),并且您的示例数据恰好被覆盖。此解决方案还将输入视为数据。
hjson -j invalid.json

相关问题