jq过滤器通过比较里面的对象来删除重复项

时间:2017-07-06 12:24:38

标签: json object duplicates jq

我正在尝试将JSON行转换为JSON,并在此过程中尝试通过比较对象的值来查找和删除重复项。

例如:

{"headline": "sample headline 1", "title": "sample title 1", "href": "sample link 1", "day": " Fri, 7 Jul 2017 , 8:30PM ", "tags": "tag1"}
{"headline": "sample headline 2", "title": "sample title 2", "href": "sample link 2", "day": " Fri, 7 Jul 2017 , 8:30PM ", "tags": "tag2"}
{"headline": "sample headline 3", "title": "sample title 3", "href": "sample link ", "day": " Fri, 7 Jul 2017 , 8:30PM ", "tags": "tag3"}
{"headline": "sample headline 4", "title": "sample title 1", "href": "sample link 4", "day": " Fri, 7 Jul 2017 , 8:30PM ", "tags": "tag4"}

现在我想比较第一个JSON行和第四个JSON行的title,如果标题相同,我想省略其中一个条目。

我只能通过比较所有对象将其转换为JSON并删除重复项:

jq --slurp [.[]] | unique

但这比较了里面的所有对象,而我只想比较一个对象并删除整行。我怎么能这样做?

1 个答案:

答案 0 :(得分:0)

用语言说:

  

..比较第一个JSON行和第四个JSON行的标题,如果标题相同,我想省略其中一个条目。

在jq:

jq -s 'if .[0].title == .[3].title then del(.[0]) else . end'

用语言说:

  

查找并删除重复项[基于.title]

在jq:

INDEX(.title) | [.[]]

除了简洁之外,在这里使用INDEX/1(例如vs uniquegroup_by)的最大好处是它不会产生排序成本。

(如果您的jq没有INDEX,那么只需从https://github.com/stedolan/jq/blob/master/src/builtin.jq复制其定义

使用-f选项

假设您有jq 1.5并且名为program.jq的文件包含以下文本:

def INDEX(stream; idx_expr):
  reduce stream as $row ({};
    .[$row|idx_expr|
      if type != "string" then tojson
      else .
      end] |= $row);
def INDEX(idx_expr): INDEX(.[]; idx_expr);

INDEX(.title) | [.[]]

您可以按如下方式调用jq:

jq -s -f program.jq input

其中"输入"是包含JSON行(或JSON流)的文件的名称。

jq 1.4

如果您只能访问jq 1.4,那么您可以使用此变体:

def INDEX(stream; idx_expr):
  reduce stream as $row ({};
    .[$row|idx_expr|
      if type != "string" then tojson
      else .
      end] |= $row);

INDEX(.[]; .title) | [.[]]

jq 1.3

jq 1.3已经过时但如果您无法升级,那么就目前而言,只需使用上面的版本,将tojson替换为tostring即可。甚至只是:

def INDEX(f): map( {(f|tostring): . } ) | add;