You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用jq的unique_by基于两个键去重并保留其他字段?

基于多键(name+url)的JSON数组去重方案

问题描述

我了解如何通过单个键实现去重,使用的是unique_by('.[].name')。现在我希望基于两个键(如name和url)进行去重,同时保留输入中的其他字段,请问该如何操作?

示例输入:

[
  {
    "name": "abc",
    "url": "https://aa.com",
    "created_at": "2022-09-30T11:17:33.181Z"
  },
  {
    "name": "bb",
    "url": "https://ddd.com",
    "created_at": "2022-09-30T11:14:33.180Z"
  },
  {
    "name": "abc",
    "url": "https://aa.com",
    "created_at": "2022-09-30T11:14:33.180Z"
  }
]

预期输出:

[
  {
    "name": "abc",
    "url": "https://aa.com",
    "created_at": "2022-09-30T11:17:33.181Z"
  },
  {
    "name": "bb",
    "url": "https://ddd.com",
    "created_at": "2022-09-30T11:14:33.180Z"
  }
]

解决方案

基础去重(保留首次出现的对象)

直接给unique_by传入一个生成复合键的表达式,把需要作为判断依据的两个字段组合成数组即可:

jq 'unique_by([.name, .url])' input.json

原理很直接:[.name, .url]会为每个对象生成一个包含name和url的数组,unique_by会基于这个复合数组判断对象是否重复——只要两个对象的name和url完全一致,就会被判定为重复项,最终只保留数组中首次出现的那个对象,同时完整保留该对象的所有其他字段(比如示例里的created_at)。

进阶:保留最新的对象

如果需要在重复组中保留created_at时间最新的对象,可以先按时间排序再去重:

jq 'sort_by(.created_at | fromdateiso8601) | reverse | unique_by([.name, .url])' input.json

步骤拆解:

  1. sort_by(.created_at | fromdateiso8601):把所有对象按created_at时间升序排列(最早的在前)
  2. reverse:反转数组,让最新的对象排在前面
  3. unique_by([.name, .url]):此时去重会保留每个重复组中排在最前面的最新对象

内容的提问来源于stack exchange,提问作者kingsec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:55:17