首页 > 解决方案 > 使用 jq 将 JSON 解析为数组 - bash

问题描述

我的 JSON 看起来像这样:

[
  {
    "file": "aaa.txt",
    "destination": 1
  },
  {
    "file": "bbb.txt",
    "destination": 2
  },
  {
    "file": "ccc.txt",
    "destination": 3
  },
  {
    "file": "ddd.txt",
    "destination": 4
  },
  {
    "file": "eee.txt",
    "destination": 9
  }
]

我正在尝试使用命令 jq 在 bash 中构建一个脚本,以获取 JSON 中的项目数并使用文件的值,第二个命令中的目标。为了实现我使用的第一个

count=$(curl 'http://mypage/json' | jq length)

我得到了这个元素的数量(计数)(在这种情况下为 5)。接下来我想构建从5到1的while循环以将文件值放入(nomen omen)文件中(循环中的脚本应该创建名为[destination]的文件,其中[file]作为内容(例如:对于firstone文件应该调用1 aaa.txt 作为内容)。而且......这是我的问题 - 我怎样才能将我的 JSON 放入数组(或其他东西)?我尝试使用

arr=$(curl 'http://mypage/json' | jq'.[]')

但它将整个json作为一个。你能帮我吗?

标签: jsonbashjq

解决方案


使用 jq 解决问题有几种合理的方法,但都有一个共同点,即 jq 只被调用一次。既然bash是标签之一,那么如果“目标”文件名是合法的,你可以做的比:

while IFS= read -r destination; do
    IFS= read -r file
    printf "%s" "$file" > "$destination"
done < <(jq -r '.[] | .destination,.file' input.json )

但是,这也假定字段的内容不包含“换行符”或 NUL 字符。如果其中任何一个可能包含文字换行符,请参见下文。

此外,检查文件名的有效性和/或处理因尝试写入指定文件名失败而引起的错误几乎肯定会更好。参见示例Windows 和 Linux 目录名称中禁止使用哪些字符?

处理换行符

假设键值不包含 NUL 字符:

while IFS= read -r -d '' destination; do
    IFS= read -r -d '' file
    printf "%s" "$file" > "$destination"
done < <(jq -rj '.[] | map_values(tostring+"\u0000") | .destination,.file' input.json )

推荐阅读