【问题标题】:Sorting Numerically with awk (gawk)使用 awk (gawk) 对数字进行排序
【发布时间】:2014-05-05 04:44:43
【问题描述】:

为了解决question,我编写了以下gnu-awk 脚本并遇到了排序问题(应该先阅读手册)。

来自手册:

因为 IGNORECASE 影响字符串比较,所以 IGNORECASE 的值 还会影响 asort() 和 asorti() 的排序。另请注意, 语言环境的排序顺序不起作用;比较是基于 仅针对字符值。

这是建议的解决方案:

awk '{
    lines[$0]=length($0)
}
END {
    for(line in lines) { tmp[lines[line],line] = line }
    n = asorti(tmp)
    for(i=1; i<=n; i++) {
        split(tmp[i], tmp2, SUBSEP); 
        ind[++j] = tmp2[2]
    }
    for(i=n; i>0; i--)
        print ind[i],lines[ind[i]]
}' file
aaaaa foo 9
aaa foooo 9
aaaa foo 8
aaa foo 7
as foo 6
a foo 5
aaaaaaa foooo 13

我尝试添加 0 来强制输入数字类型,但无法达到所需的输出。有没有办法在awk/gawk 中模拟数字排序?

输入文件:

aaa foooo
aaaaaaa foooo
a foo
aaa foo
aaaaa foo
as foo
aaaa foo

期望的输出:

aaaaaaa foooo
aaaaa foo     # Doesnt matter which one comes first (since both are same size)
aaa foooo     # Doesnt matter which one comes first (since both are same size)
aaaa foo
aaa foo
as foo
a foo

脚本输出中显示的数字仅用于说明排序是如何完成的。

【问题讨论】:

  • 您尝试过使用sort 之类的东西吗?你在哪里定义SUBSEP?期望的输出是什么?
  • 底部的文字是输入还是输出?您想按末尾的数字对这些行进行排序吗?
  • @AlexejMagura SUBSEP 是一个 awk 内置函数。他试图避免sort。这就是重点。
  • @TomFenech 他试图按行的长度进行排序,这些数字仅用于说明为什么 awk 以它的方式对行进行排序。
  • @EtanReisner 谢谢。这就是 input 文件?

标签: awk gawk


【解决方案1】:

看看这个例子,Jaypal,你会得到:

kent$  cat f
3333333
50
100
25
44

kent$  awk '{a[$0]}END{asorti(a,b);for(i=1;i<=NR;i++)print b[i]}' f          
100
25
3333333
44
50

kent$  awk '{a[$0]}END{asorti(a,b,"@val_num_asc");for(i=1;i<=NR;i++)print b[i]}' f
25
44
50
100
3333333

【讨论】:

  • +1:谢谢肯特。我应该更好地查看gawk 手册。这有助于解决问题。老实说,我从来不知道有这么多可用于排序的选项。
  • +1 我没有注意到第三个参数被添加到 asorti(),它很有用!
  • 这很奇怪,但是最后一个 awk 给了我这样的行:44,100,333333,50,25。我不知道为什么。
  • @BrunoBronosky 也许您想检查您使用的是哪个 gawk 版本,以及该版本是否支持 asorti(a,b,c)
  • 我确实使用您的示例文件对数字进行了排序,但是当输入文件有更大的数字时它不起作用,您知道为什么吗?例如以下数字未按数字排序:5695669340 4690291506 511687106 515604480 632193024 2124447744
【解决方案2】:

您遇到的问题是您正在调用 asorti() ,它对数组索引进行排序,并且根据定义,所有 awk 数组索引都是字符串,因此排序是基于字符串的。例如,您可以使用str=sprintf("%20s",num); gsub(/ /,0,str) 填充一些前导零,这样每个字符串的长度都相同(例如,001、010 和 100 而不是 1、10、100)或通过 asort() 而不是对数组元素使用和排序使用 asorti() 的索引,因为数组元素可以是字符串或数字。

【讨论】:

  • 谢谢@Ed,答案确实帮助了我。这个错误在我的思考过程中,我很欣赏这个解释。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
  • 2017-01-26
  • 2018-09-13
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 2020-09-21
相关资源
最近更新 更多