注意:此解决方案假设 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"
]