【问题标题】:jq filter to remove duplicates by comparing objects insidejq过滤器通过比较内部的对象来删除重复项
【发布时间】:2017-07-06 12:24:38
【问题描述】:

我正在尝试将 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

但这会比较内部的所有对象,而我只想比较一个对象并删除整行。我该怎么做?

【问题讨论】:

    标签: json object duplicates jq


    【解决方案1】:

    言辞:

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

    在jq中:

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

    言辞:

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

    在jq中:

    INDEX(.title) | [.[]]
    

    除了简洁之外,在这里使用INDEX/1(例如与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;
    

    【讨论】:

    • 在未定义索引时,您能帮我提供确切的代码吗?因此,根据标题查找并删除重复项。索引(.title) | [.[]] 返回和错误。我是 jq 的新手。谢谢
    • 我尝试使用上面的代码得到以下错误错误:tojson is not defined if type != "string" then tojson ^^^^^^ error: too many arguments to INDEX (expected 1 but got 2) def INDEX(idx_expr): INDEX(.[]; idx_expr); ^^^^^ 2个编译错误
    • 非常感谢。完美运行。我的版本确实是 1.3,这就是出现错误的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    相关资源
    最近更新 更多