使用awk进行数字排序(gawk)

使用awk进行数字排序(gawk),awk,gawk,Awk,Gawk,为了解决一个问题,我编写了以下gnuawk脚本,遇到了排序问题(应该先阅读手册) 从手册中: 由于IGNORECASE会影响字符串比较,因此IGNORECASE的值 还影响asort()和asorti()的排序。还请注意 区域设置的排序顺序不起作用;比较是基于 仅在字符值上 这就是提议的解决方案: awk '{ lines[$0]=length($0) } END { for(line in lines) { tmp[lines[line],line] = line }

为了解决一个问题,我编写了以下
gnuawk
脚本,遇到了排序问题(应该先阅读手册)

从手册中:

由于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
期望输出:
脚本输出中显示的数字仅用于说明排序是如何完成的

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

见此示例,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
kent$f类
3333333
50
100
25
44

肯特$awk'{a[$0]}END{asorti(a,b);用于(i=1;我试过使用类似于排序的东西吗?
sort
?你在哪里定义
subsp
?期望的输出是什么?底部的文本是输入还是输出?你想按末尾的数字对这些行进行排序?@AlexejMagura
subsp
是一个
awk
内置。他试图避免
sort
这就是问题所在。@TomFenech他试图按行的长度排序,这些数字只是为了说明为什么awk会这样排序。@EtanReisner谢谢。这就是输入文件吗?+1:谢谢你,肯特。我应该更好地看一下
gawk
手册。这有助于解决问题。我真的不知道我们在那里有这么多选项可供排序。+1我没有注意到第三个参数被添加到asorti(),这是一个有用的参数!这很奇怪,但最后一个awk按以下顺序给我行:44100333333,50,25。我不明白为什么。@BrunoBronosky也许你想检查你正在使用的是哪个gawk版本,以及该版本是否支持
asorti(a、b、c)
我确实使用您的示例文件对数字进行排序,但当输入文件中的数字较大时,它不起作用,您知道为什么吗?例如,以下数字不按数字排序:5695669340 4690291506 51168 7106 515604480 632193024 2124447744谢谢@Ed,答案确实帮助了我。错误在我的思考过程中,我感谢您的解释离子+1
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
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