jq-筛选JSON数组(如果不包含不起作用)

时间:2019-11-19 21:10:48

标签: json parsing jq

我在解析JSON文件时遇到麻烦,我想从该文件中提取不包含字符串“ To Do”作为标签的元素。

这是我要解析的文件

[
  {
    "id": 1,
    "title": "Task A",
    "labels": [
      "Low",
      "To Do"
    ]
  },
  {
    "id": 2,
    "title": "Task B",
    "labels": [
      "Medium",
      "Done"
    ]
  },
  {
    "id": 3,
    "title": "Task C",
    "labels": [
      "High",
      "To Do"
    ]
  }
]

我可以使用以下命令成功提取包含“待办事项”的元素:

$ cat tmp.json | jq 'keys[] as $k | select(.[$k].labels[] | contains("To Do")) | "\(.[$k].id) -- \(.[$k].title) -- \(.[$k].labels)"'
"1 -- Task A -- [\"Low\",\"To Do\"]"
"3 -- Task C -- [\"High\",\"To Do\"]"

但是,当我否定条件jq时,其行为如下:

$ cat tmp.json | jq 'keys[] as $k | select(.[$k].labels[] | contains("To Do") | not) | "\(.[$k].id) -- \(.[$k].title) -- \(.[$k].labels)"'
"1 -- Task A -- [\"Low\",\"To Do\"]"
"2 -- Task B -- [\"Medium\",\"Done\"]"
"2 -- Task B -- [\"Medium\",\"Done\"]"
"3 -- Task C -- [\"High\",\"To Do\"]"

这里唯一的区别是条件的取反,但是所有三个元素都被打印,而我要过滤的元素被打印了两次。

谢谢。

2 个答案:

答案 0 :(得分:3)

对于这样一个琐碎的任务,您的查询似乎有点复杂(我没有调试,但是您可能在那里误用了contains;我怀疑它对每个数组元素都运行了,而不仅仅是数组本身运行一次)

无论如何,这是一种干净直接的方法:

.[] | select(.labels | index("To Do") | not) | "\(.id) -- \(.title) -- \(.labels)"

并避免UUOC顺滑。

答案 1 :(得分:3)

我会选择all(_; . != "To Do")

.[] 
| select( all(.labels[]; . != "To Do"))
|  "\(.id) -- \(.title) -- \(.labels)"