Unix 下如何对数组中的数字进行排序?

Unix 下如何对数组中的数字进行排序?

我在想是否存在这样一个简单函数的名称,它返回数组中数字的顺序。我真的很想通过极简的方式和基本的 Unix 命令来进行这个排名,但除了基本的查找和循环之外,我无法想到任何东西,这不是那么优雅。假设你有一个数字数组

17 
94 
3 
52 
4 
4 
9

重复项仅收到相同 ID 的预期输出;如何处理重复项并不重要,因此可以走捷径:

4 
6 
1 
5 
2 
2 
3        

动机:我今天看到许多用户使用许多不同的方法来解决这个问题,并使用电子表格执行许多手动步骤;所以我开始思考用极简主义的方式来做这件事。

将排名算法与 Google 的平均排名进行比较

在 Google 电子表格中,执行此操作=arrayformula(rank.AVG(A:A,A:A,true)),您将得到作为升序的基准,如第一个预期输出

17  5
94  7
3   1
52  6
4   2.5
4   2.5
9   4

您可以看到我的初始排名算法有偏差。我认为能够设置数据集位置在这里会很有帮助。

答案1

如果该列表位于 a 中file,每行一个,我会执行以下操作:

sort -nu file |
  awk 'NR == FNR {rank[$0] = NR; next}
      {print rank[$0]}' - file

如果它在zsh $array

sorted=(${(nou)array})
for i ($array) echo $sorted[(i)$i]

这与上面版本的原理相同awk是按数字 ( / ) 排序 ( / )、唯一 ( / ) 的元素列表中的索引NR/ 。(i)-n(n)sort(o)-u(u)

对于您的平均排名:

sort -n file |
  awk 'NR == FNR {rank[$0] += NR; n[$0]++; next}
  {print rank[$0] / n[$0]}' - file

这使:

5
7
1
6
2.5
2.5
4

(用于sort -rn颠倒顺序,就像您的谷歌电子表格版本)。

答案2

nl x | sort  -k 2n | nl | sort -k 2n | cut -f1

...在重复的情况下它的行为略有不同:

 nl x | sort  -k 2n | nl | sort -k 2n | cut -f1,3
 5  17 
 7  94 
 1  3 
 6  52 
 2  4 
 3  4 
 4  9

答案3

仅使用 GNU awk:

awk '
    FNR == NR {numbers[$1]=1; next} 
    FNR == 1 {
        n = asorti(numbers, sorted, "@ind_num_asc")
        for (i=1; i<=n; i++) rank[sorted[i]] = i
    }
    {print rank[$1]}
' file file

相关内容