如果键存在于另一个对象中,则过滤json对象

时间:2019-04-10 23:15:24

标签: json bash command-line jq

我有两个文件

file1.json

{
  "a": "x1",
  "b": "y1",
  "c": "z1"
}

file2.json

{
  "a": "x2",
  "b": "y2"
}

由于file2中已经存在a和b,因此我想输出仅包含c的新对象。这些值并不重要。

{
  "c": "z1"
}

我尝试过

jq -s '.[0] | to_entries | map(select(.key | in(.[1]) | not)) | from_entries' temp1.json temp2.json

但是我遇到以下错误:

jq: error (at temp2.json:4): Cannot index string with number

有趣的是,当我尝试:

jq -s '.[0] | to_entries | map(select(.key | in({"a": "x2", "b": "y2"}) | not)) | from_entries' file1.json file2.json

我得到正确的输出。因此,似乎jq会将。[1]当作int对待?而不是json对象。

3 个答案:

答案 0 :(得分:0)

到目前为止,这个“ hack”对我来说是成功的。我很好奇是否还有更好的方法。

jq -s '. as $input | $input[0] | to_entries | map(select(.key | in($input[1]) | not)) | from_entries' temp1.json temp2.json

答案 1 :(得分:0)

这是使用reduce的简单方法:

jq -n --argfile one file1.json --argfile two file2.json '
 reduce ($two|keys_unsorted)[] as $k ($one; delpaths([[$k]]))'

这是仍然使用delpaths的更有效的过滤器:

$one | delpaths($two|keys_unsorted|map([.]))

答案 2 :(得分:0)

这是执行对象减法的通用功能:

# remove from $x all the keys that occur in $y
def minus($x; $y):
  ((($x + $y)|to_entries) - ($y|to_entries))
  | from_entries;

这可以通过多种方式来解决问题,例如调用:

jq -n -f program.jq file1.json file2.json

其中program.jq包含上述定义,后跟:

minus(input; input)