如何从bash中反复增量生成调用jq的JSON

  • 本文关键字:调用 jq JSON bash json bash shell jq
  • 更新时间 :
  • 英文 :


是否有一些公认的使用bash和jq生成JSON文档的"最佳实践"?我有一个脚本来收集各种数据,为了更容易使用其他工具进行进一步处理,我想以JSON格式输出数据。因此,我使用jq来确保所有引用等都正确完成,如以下答案中所建议的:https://stackoverflow.com/a/48470227/75652.然而,我正在努力解决如何零碎地生成它,而不是在最后生成一个巨大的jq调用。例如,类似的东西


read foo <<<$(</path/to/some/oneliner/file)
jq -n --arg f $foo '{foo: $f}'
bar=$(some_command)
jq -n --arg b $bar '{bar: $b}'

将生成两个独立的对象(可以使用支持各种或多或少非正式的"JSON流"格式的工具进行处理,包括jq),而我想要一个单独的对象,比如


{ "foo": SOMETHING, "bar": SOMETHING_ELSE }

但我不能对多个jq调用执行此操作,因为jq会抱怨不完整的JSON格式不正确。

为了进一步增加一些复杂性,在某些情况下,我需要生成嵌套的JSON结构。在另一种类似python的语言中,我只需要将所有数据放在一组嵌套字典中,然后最终将其转储到JSON中,但bash中的嵌套字典似乎非常乏味。。

您可以为下一个jq命令保存和处理中间JSON:

#!/usr/bin/env bash
read -r foo <a.txt
json="$(jq -n --arg f "$foo" '{foo: $f}')"

bar="$(pwd)"
jq -n --arg b "$bar" "$json"'+{bar: $b}'
# or alternatively
jq --arg b "$bar" '.bar=$b' <<<"$json"

当达到一定的复杂性时(或者当我需要在转换之间从外部处理一些数据时),我通常会使用类似的东西

jq --slurpfile foo <(

# first inner shell script
read foo <<<$(</path/to/some/oneliner/file)
jq -n --arg f $foo '{foo: $f}'
) --slurpfile bar <(
# second inner shell script
bar=$(some_command)
jq -n --arg b $bar '{bar: $b}'
) -n '$foo[0] + $bar[0]'

这样,最外层的jq调用可能仍然有自己的"真实"输入,并且内部调用在作用域中的所有bash变量都可以很好地维护。

Q使得CCD_ 1和CCD_,在这种情况下,您可以使用作为模型

jq -n --arg f "$foo" --arg b "$bar" '.foo = $f | .bar = $b' 

当然,如果$foo的值很大,最好使用面向文件的命令行使jq可以使用这些值选项,例如--slurpfile

如果某些值的计算取决于大文件,然后多次调用jq可能是有意义的。因为case,对jq进行N次调用以封送值,然后进行一次额外的调用将它们组装成一个JSON对象(可能使用jq-s add)似乎非常合理。

Q标题中建议的替代方案是为了创建对jq的调用管道,例如:

jq -n --argfile f <(some nasty stuff) '.foo = $f' |
jq  --argfile b <(some more nasty stuff) '.bar = $b' | ...

最后,如果$bar在某种程度上依赖于$foo,那么如果这种依赖可以在jq程序中表达,您可以在底层使用一个更复杂的jq程序调用jq中的值。

最新更新