用awk(gawk)数字排序

jay*_*ngh 2 awk gawk

为了解决问题,我编写了以下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
Run Code Online (Sandbox Code Playgroud)

我尝试添加0以强制数字类型,但无法达到所需的输出.有没有办法可以模拟数字排序awk/gawk

输入文件:

aaa foooo
aaaaaaa foooo
a foo
aaa foo
aaaaa foo
as foo
aaaa foo
Run Code Online (Sandbox Code Playgroud)

期望的输出:

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
Run Code Online (Sandbox Code Playgroud)

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

Ken*_*ent 13

看到这个例子,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
Run Code Online (Sandbox Code Playgroud)


Ed *_*ton 9

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