首页 > 解决方案 > jq unique_by 选择排序后的第一个元素

问题描述

我有一系列具有相关信号级别的无线接入点。我想将其减少为具有最高信号的唯一 SSID。

# cat aps.json 
{
 "AP" : [
  { "SSID"  : "Bart",   "Signal" : -20 },
  { "SSID"  : "Lisa",   "Signal" : -19 },
  { "SSID"  : "Homer",  "Signal" : -91 },
  { "SSID"  : "Homer",  "Signal" : -92 },
  { "SSID"  : "Lisa",   "Signal" : -92 },
  { "SSID"  : "Lisa",   "Signal" : -21 },
  { "SSID"  : "Homer",  "Signal" : -90 },
  { "SSID"  : "Bart",   "Signal" : -21 },
  { "SSID"  : "Bart",   "Signal" : -22 }
  ]
}

我尝试使用 sort_by 按 Signal 进行排序,这似乎不知道负数。我使用 reverse 将最小的负数放在第一位。然后 unique_by 似乎没有选择第一个元素。

# jq '.AP | sort_by(.Signal) | reverse | unique_by(.SSID)' aps.json        
[
  {
    "SSID": "Bart",
    "Signal": -22
  },
  {
    "SSID": "Homer",
    "Signal": -92
  },
  {
    "SSID": "Lisa",
    "Signal": -19
  }
]

似乎选择了流中的最后一个 Bart、Second Homer 和 First Lisa。

这个 jq unique_by - 选择剩余元素的答案似乎暗示这在 jq 的更高版本或至少 1.5 中已修复,但我正在运行 1.5

# jq --version
jq-1.5

标签: jsonsortinguniquejq

解决方案


我认为问题是 unique_by() 在选择元素之前进行了预排序。即它正在使用我刚刚排序的数据。

答案是呈现预先排序到 unique_by() 的数据。

难题的最后一块是删除反向,因为 sort_by 可以否定字段。

这似乎奏效了。

# jq '.AP | sort_by(.SSID,-.Signal)| unique_by(.SSID)' aps.json 
[
  {
    "SSID": "Bart",
    "Signal": -20
  },
  {
    "SSID": "Homer",
    "Signal": -90
  },
  {
    "SSID": "Lisa",
    "Signal": -19
  }
]

推荐阅读