【问题标题】:Sort an associative array in awk在 awk 中对关联数组进行排序
【发布时间】:2011-01-28 08:06:12
【问题描述】:

我在 awk 中有一个关联数组,填充如下:

chr_count[$3]++

当我尝试打印我的chr_counts 时,我使用这个:

for (i in chr_count) {
    print i,":",chr_count[i];
}

但并不奇怪,i 的顺序没有以任何方式排序。 有没有一种简单的方法来遍历 chr_count 的排序键?

【问题讨论】:

标签: sorting arrays awk associative


【解决方案1】:

不要使用 asort,而是使用 asorti(source, destination) 将索引排序到一个新数组中,您不必复制该数组。

然后你可以使用目标数组作为指向源数组的指针。

对于您的示例,您可以像这样使用它:

n=asorti(chr_count, sorted)
for (i=1; i<=n; i++) {
        print sorted[i] " : " chr_count[sorted[i]]
}

【讨论】:

  • 哇,尽管在文档中阅读过它,但完全忘记了这一点。这绝对是更好的答案。
  • asorti 不适用于 nawk-20121220-2.fc20.x86_64。
  • @CristianCiupitu:抱歉asorti 是 GAWK 特有的。事实上,我认为nawk 没有任何内置的排序功能。
  • GNU Awk 的 documentation 确实提到:“asort() 和 asorti() 是 gawk 扩展;它们在兼容模式下不可用(参见 Options)”。
【解决方案2】:

您可以使用排序命令。例如

for ( i in data )
 print i ":", data[i]  | "sort"

【讨论】:

    【解决方案3】:

    我最近遇到了这个问题,发现使用 gawk 我可以设置 PROCINFO["sorted_in"] 的值来控制迭代顺序。我通过在线搜索 PROCINFO 找到了一个有效值列表,并登陆了这个 GNU Awk 用户指南页面:https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html

    这列出了@{ind|val}_{num|type|str}_{asc|desc} 形式的选项:

    • ind 按键(索引)排序,val 按值排序。
    • num 按数字排序,str 按字符串排序,type 按指定类型排序。
    • asc 升序排列,desc 降序排列。

    我只是用过:

    PROCINFO["sorted_in"] = "@val_num_desc"
    for (i in map) print i, map[i]
    

    并且输出按值的降序排列。

    【讨论】:

      【解决方案4】:

      请注意,asort()asorti() 是 gawk 特有的,而 awk 不知道。对于普通的 awk,您可以创建自己的 sort() 或从其他地方获取。

      【讨论】:

        【解决方案5】:

        这是直接取自the documentation:

         populate the array data
         # copy indices
         j = 1
         for (i in data) {
             ind[j] = i    # index value becomes element value
             j++
         }
         n = asort(ind)    # index values are now sorted
         for (i = 1; i <= n; i++) {
             do something with ind[i]           Work with sorted indices directly
             ...
             do something with data[ind[i]]     Access original array via sorted indices
         }
        

        【讨论】:

        • 当心,这个解决方案是有缺陷的,因为这最终会丢失原始数组中具有相同值的键。从另一个线程接受的解决方案对如何解决这个问题有一个想法:stackoverflow.com/a/5345056/95750
        • @haridsv 不,我不这么认为。这个问题是关于按键排序,而不是按值排序,同一个键不能有两个值,所以这里没有问题。您指出的另一个问题是关于按值排序(实际上可能并非都是不同的),因此,如果您尝试为此使用此代码,那将是一个问题。但是,如果您将它用于它的目的,这并没有缺陷。
        • 抱歉.. 我将索引代码误读为“翻转”键/值,但重读后,我注意到您使用的是不断增加的数字作为索引,而不是原始值。感谢您回来澄清。
        猜你喜欢
        • 2011-07-17
        • 1970-01-01
        • 1970-01-01
        • 2015-06-11
        • 1970-01-01
        • 2010-09-11
        • 2011-12-20
        相关资源
        最近更新 更多