使用ID数组选择或排除多个对象

时间:2016-07-21 15:51:29

标签: json bash jq

我有以下JSON:

[
  {
    "id": "1",
    "foo": "bar-a",
    "hello": "world-a"
  },
  {
    "id": "2",
    "foo": "bar-b",
    "hello": "world-b"
  },
  {
    "id": "10",
    "foo": "bar-c",
    "hello": "world-c"
  },
  {
    "id": "42",
    "foo": "bar-d",
    "hello": "world-d"
  }
]

我在变量中有以下数组存储:["1", "2", "56", "1337"](注意ID是字符串,可能包含任何常规字符)。

所以,谢谢to this SO,我找到了一种过滤原始数据的方法。 jq 'jq '[.[] | select(.id == ("1", "2", "56", "1337"))]' ./data.json(注意数组被括号括起而不是括号)产生:

[
  {
    "id": "1",
    "foo": "bar-a",
    "hello": "world-a"
  },
  {
    "id": "2",
    "foo": "bar-b",
    "hello": "world-b"
  }
]

但我也喜欢做相反的事情(基本上不包括ID而不是选择它们)。使用select(.id != ("1", "2", "56", "1337"))不起作用,使用jq '[. - [.[] | select(.id == ("1", "2", "56", "1337"))]]' ./data.json似乎非常难看,并且它不适用于我的实际数据(aws ec2 describe-instances的输出)。

你有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:1)

要包含它们,您需要验证id是保持集中的任何值。

$ jq --argjson include '["1", "2", "56", "1337"]' 'map(select(.id == $include[]))' ...

要排除它们,您需要验证所有值都不在您的排除集中。但是,获取原始集合并删除排除集合中的项目可能更容易。

$ jq --argjson exclude '["1", "2", "56", "1337"]' '. - map(select(.id == $exclude[]))' ...

答案 1 :(得分:0)

以下是使用内部的解决方案。假设你运行jq为

jq -M --argjson IDS '["1","2","56","1337"]' -f filter.jq data.json

filter.jq

map( select([.id] | inside($IDS)) )

生成来自data.json数组中的$IDS的ID:

[
  {
    "id": "1",
    "foo": "bar-a",
    "hello": "world-a"
  },
  {
    "id": "2",
    "foo": "bar-b",
    "hello": "world-b"
  }
]

filter.jq

map( select([.id] | inside($IDS) | not) )

生成data.json中不在$IDS数组中的ID:

[
  {
    "id": "10",
    "foo": "bar-c",
    "hello": "world-c"
  },
  {
    "id": "42",
    "foo": "bar-d",
    "hello": "world-d"
  }
]