如何使用 jq 获取两个 JSON 数组的交集

2024-01-27

给定数组 X 和 Y(最好都作为输入,但否则,一个作为输入,另一个硬编码),如何使用 jq 输出包含两者共有的所有元素的数组?例如f 的值是多少,使得

echo '[1,2,3,4]' | jq 'f([2,4,6,8,10])'

会输出

[2,4]

?

我尝试过以下方法:

map(select(in([2,4,6,8,10])))  --> outputs [1,2,3,4]
select(map(in([2,4,6,8,10])))  --> outputs [1,2,3,4,5]

注意:此解决方案假设 array1 没有重复项。

简单说明

所有这些答案的复杂性掩盖了对原理的理解。这很不幸,因为原理很简单:

  • array1 减去 array2 返回:
  • array1 中剩下的所有内容
  • 删除 array2 中的所有内容后
  • (并丢弃 array2 的其余部分)

简单演示

# From array1, subtract array2, leaving the remainder
$ jq --null-input '[1,2,3,4] - [2,4,6,8]'
[
  1,
  3
]

# Subtract the remainder from the original
$ jq --null-input '[1,2,3,4] - [1,3]'
[
  2,
  4
]

# Put it all together
$ jq --null-input '[1,2,3,4] - ([1,2,3,4] - [2,4,6,8])'
[
  2,
  4
]

comm Demo

def comm:
  (.[0] - (.[0] - .[1])) as $d |
    [.[0]-$d, .[1]-$d, $d]
;

有了这种理解,我就能够模仿*尼克斯comm command https://man7.org/linux/man-pages/man1/comm.1.html

如果没有选项,则生成三列输出。第一栏 包含 FILE1 特有的行,第二列包含特有的行 到 FILE2,第三列包含两个文件共有的行。

$ echo 'def comm: (.[0]-(.[0]-.[1])) as $d | [.[0]-$d,.[1]-$d, $d];' > comm.jq
$ echo '{"a":101, "b":102, "c":103, "d":104}'                        > 1.json
$ echo '{         "b":202,          "d":204, "f":206, "h":208}'      > 2.json

$ jq --slurp '.' 1.json 2.json
[
  {
    "a": 101,
    "b": 102,
    "c": 103,
    "d": 104
  },
  {
    "b": 202,
    "d": 204,
    "f": 206,
    "h": 208
  }
]

$ jq --slurp '[.[] | keys | sort]' 1.json 2.json
[
  [
    "a",
    "b",
    "c",
    "d"
  ],
  [
    "b",
    "d",
    "f",
    "h"
  ]
]

$ jq --slurp 'include "comm"; [.[] | keys | sort] | comm' 1.json 2.json
[
  [
    "a",
    "c"
  ],
  [
    "f",
    "h"
  ],
  [
    "b",
    "d"
  ]
]

$ jq --slurp 'include "comm"; [.[] | keys | sort] | comm[2]' 1.json 2.json
[
  "b",
  "d"
]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 jq 获取两个 JSON 数组的交集 的相关文章

随机推荐