如何创建一个 JSON 数组并将 JSON 对象附加到它?

Fli*_*xRo 0 arrays bash json jq

我正在从给定的数据创建 JSON 对象。如果创建了 JSON 对象,则应将其附加到存储在 bash 变量中的 JSON 数组。这批 JSON 对象稍后应该通过 curl 发送。

代码是:

declare -a data=('10.4' '100.23' '20.02');
batch="[]"
for data_object in "${data[@]}"; do
    json=$(jq -n --arg inf $data_object '{data: $inf|tonumber}')
    batch=$(jq '$batch += ["$json"]')
done
Run Code Online (Sandbox Code Playgroud)

n 次循环后的预期结果应该是:

[
   {
      "data": 10.4
   },
   {
      "data": 100.23
   },
   {
      "data": 20.02
   }
]
Run Code Online (Sandbox Code Playgroud)

我不断收到此错误:jq: error: $batch is not defined at <top-level>, line 1:。我该如何解决这个问题?

pea*_*eak 5

毫无疑问,您可以通过以下方式更新您的程序batch

batch=$(jq --argjson json "$json" '. + [$json]' <<< "$batch")
Run Code Online (Sandbox Code Playgroud)

但是,您采用的方法似乎既脆弱又低效。您是否考虑过将文件中的所有项目(作为 JSON 实体流)累积起来,以及何时需要将它们捆绑到一个数组中,使用jq -s .?

在给出的特定示例中,实际上编写以下内容就足够了:

printf "%s\n" "${data[@]}" |
    jq -n '[{data: inputs}]' |
    curl -d @- <OTHER CURL OPTIONS>
Run Code Online (Sandbox Code Playgroud)

也就是说,您可以通过管道直接进入curl.

请注意,调用 totonumber是不必要的,无论是否知道所有data项目都是数字。作为参考,tonumber通常在(tonumber? // .)字符串或其他输入不是数字的情况下用于习语。

另一种变体

如果要对 jq 无法轻松处理的每个数据元素采取其他操作:

batch=$(
   (
       for data_object in "${data[@]}"; do
           jq -n --argjson inf "$data_object" '{data: $inf}'
       done
   ) | jq -s .
)
Run Code Online (Sandbox Code Playgroud)

在这里,tonumber不需要调用,这一次感谢--argjson.