Bash脚本从非结构化JSON文件中提取所有特定的键值

时间:2019-04-25 01:37:41

标签: json bash jq

我试图从下面的JSON文件中的特定键中提取所有值。

{
  "tags": [
    {
      "name": "xxx1",
      "image_id": "yyy1"
    },
    {
      "name": "xxx2",
      "image_id": "yyy2"
    }
  ]
}

我使用下面的代码来获取image_id键值。

echo new.json | jq '.tags[] | .["image_id"]'

我收到以下错误消息。

parse error: Invalid literal at line 2, column 0

我认为JSON文件格式不正确,或者echo调用Json文件的命令错误。

鉴于上述输入,我的预期/期望输出是:

yyy1
yyy2

要实现这一目标需要解决什么?

3 个答案:

答案 0 :(得分:0)

运行时:

echo new.json | jq '.tags[] | .["image_id"]'

...字符串new.json-不是名为new.json的文件的内容-被馈送到jq的标准输入,并且因此它将尝试解析为JSON文本。

Instead, run:

jq -r '.tags[] | .["image_id"]' <new.json

...直接打开连接到new.json的标准输入的jq(并使用-r,以避免在输出流中添加不必要的引号)。

答案 1 :(得分:0)

另外,您可能想尝试另一种询问方法-使用针对JSON的步行路径Unix工具: jtc 。这样一来,您的要求将如下所示:

bash $ <new.json jtc -w'[tags][:][image_id]'
"yyy1"
"yyy2"
bash $ 

但是,您的new.json并非结构良好,相反是结构良好。如果您的new.json确实不规则(非结构化),那么以下查询会更好地工作:

bash $ <new.json jtc -w'<image_id>l:'
"yyy1"
"yyy2"
bash $ 

答案 2 :(得分:0)

  1. 您的过滤器.tags[] | .["image_id"]

有效,但可以缩写为:

.tags[] | .image_id

甚至:

.tags[].image_id
  1. 如果要与“ image_id”键关联的值,无论该键出现在何处,都可以使用:

    .. | objects | select(has("image_id")) | .image_id

或者,如果您不介意丢掉false和null值:

.. | .image_id? // empty