二级排序awk数组

二级排序awk数组,awk,columnsorting,Awk,Columnsorting,我在下面有一个输入文件,其中字段分隔符ir“+”,我想在2级中排序。先按第三个字段,然后按升序按第二个字段 输入 到目前为止,我的代码如下,但输出不是我所需要的 awk '{split($0,f,"+") a[$0]=f[3]; }END{ n=asorti(a,b) for (i=1;i<=n;i++) print b[i]}' file.txt 110x16+255+63 178x59+223+65 1

我在下面有一个输入文件,其中字段分隔符ir“+”,我想在2级中排序。先按第三个字段,然后按升序按第二个字段

输入

到目前为止,我的代码如下,但输出不是我所需要的

awk '{split($0,f,"+")
      a[$0]=f[3];
     }END{
          n=asorti(a,b)
          for (i=1;i<=n;i++) 
          print b[i]}' file.txt
110x16+255+63
178x59+223+65
178x59+29+65
178x59+417+65
178x59+611+65
240x151+140+624
240x151+366+355
240x151+462+176
240x151+468+542
240x151+77+448
240x151+87+257

sort
是解决此问题的正确工具

$ sort -t+ -k3n -k2,2n file

110x16+255+63
178x59+29+65
178x59+223+65
178x59+417+65
178x59+611+65
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
240x151+140+624

awk
中执行此操作的一种方法是通过组合第3和第2个字段并按该键排序来创建一个新键。但是请注意,数组索引将以非数字方式进行排序。因此,我们必须通过零填充将它们转换为文本排序的等效格式。假设最大数字有5位数字(如果没有相应更改)

$awk-F+'{k1=sprintf(“%05d”,$3);k2=sprintf(“%05d”,$2);a[k1,k2]=$0}
END{n=asorti(a,d);for(i=1;i使用GNU awk和
asorti()
的另一个(不完美):

使用
“@ind\u num\u asc”
顺序如下:

1, 110x16+255+63
2, 178x59+223+65
3, 178x59+29+65
4, 178x59+417+65
5, 178x59+611+65
6, 240x151+140+624
7, 240x151+366+355
8, 240x151+462+176
9, 240x151+468+542
10, 240x151+77+448
11, 240x151+87+257

要在
awk
中执行此操作,请通过组合第3和第2个字段并按该键排序来创建一个新键。但是,您不需要执行此操作,因为
sort
已设计用于处理这些情况。感谢您的回答。我已经完成了排序,但由于这是另一个脚本的一部分,我需要管道两次。首先读取文件,然后管道到ort命令,然后通过管道再次连接到awk,以便处理结果的排序输出。我想使用一个独特的awk程序。您能告诉我如何将字段3和字段2组合为键吗?为什么您认为额外的管道是一个问题?
awk
最初没有
sort
功能。非常棒的karakfa,非常棒的技巧和co与asorti()合并。非常感谢您的帮助。我问了4次如何做,在第4次尝试中,您得到了解决方案。嗨,詹姆斯。非常好。甚至更简单的解决方案。我知道第一级是如何排序第三个字段的,但我不清楚第二个字段的升序是如何排序的。我说得太快了。似乎您的解决方案仍然没有打印输出D
$ sort -t+ -k3n -k2,2n file

110x16+255+63
178x59+29+65
178x59+223+65
178x59+417+65
178x59+611+65
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
240x151+140+624
$ awk -F+ '{k1=sprintf("%05d",$3); k2=sprintf("%05d",$2); a[k1,k2]=$0}
       END {n=asorti(a,d); for(i=1;i<=n;i++) print a[d[i]]}' file

110x16+255+63
178x59+29+65
178x59+223+65
178x59+417+65
178x59+611+65
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
240x151+140+624
awk '
{
    split($0,f,"+")
    a[$0]=f[3]                    # a["110x16+255+63"] = 63
}
END {
    OFS=", "                      # for pretty output
    n=asorti(a,a,"@val_num_asc")  # NOTICE THE THIRD ARGUMENT, using asorti but "@val..."
    for (i=1;i<=n;i++)            # "@ind..." would sort using the index
        print i,a[i]              # I wrote a over old a but you could use b
}' file
1, 110x16+255+63
2, 178x59+417+65
3, 178x59+611+65
4, 178x59+29+65
5, 178x59+223+65
6, 240x151+462+176
7, 240x151+87+257
8, 240x151+366+355
9, 240x151+77+448
10, 240x151+468+542
11, 240x151+140+624
1, 110x16+255+63
2, 178x59+223+65
3, 178x59+29+65
4, 178x59+417+65
5, 178x59+611+65
6, 240x151+140+624
7, 240x151+366+355
8, 240x151+462+176
9, 240x151+468+542
10, 240x151+77+448
11, 240x151+87+257