2级排序awk数组
2 level sort awk array
我在下面有这个输入文件,我想在 2 级中对字段分隔符“+”进行排序。先按第 3 个字段,然后按升序按第 2 个字段。
输入
240x151+140+624
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
178x59+223+65
178x59+417+65
178x59+611+65
178x59+29+65
110x16+255+63
我目前的代码如下,但输出不是我需要的。
awk '{split([=11=],f,"+")
a[[=11=]]=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
我想要获得的预期输出如下所示,并且能够根据数字索引处理数组。
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
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",); k2=sprintf("%05d",); a[k1,k2]=[=11=]}
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
另一个(不完美)使用 GNU awk 和 asorti()
的 third string argument to control comparison of array elements:
awk '
{
split([=10=],f,"+")
a[[=10=]]=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
使用 "@ind_num_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
我在下面有这个输入文件,我想在 2 级中对字段分隔符“+”进行排序。先按第 3 个字段,然后按升序按第 2 个字段。
输入
240x151+140+624
240x151+462+176
240x151+87+257
240x151+366+355
240x151+77+448
240x151+468+542
178x59+223+65
178x59+417+65
178x59+611+65
178x59+29+65
110x16+255+63
我目前的代码如下,但输出不是我需要的。
awk '{split([=11=],f,"+")
a[[=11=]]=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
我想要获得的预期输出如下所示,并且能够根据数字索引处理数组。
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
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",); k2=sprintf("%05d",); a[k1,k2]=[=11=]}
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
另一个(不完美)使用 GNU awk 和 asorti()
的 third string argument to control comparison of array elements:
awk '
{
split([=10=],f,"+")
a[[=10=]]=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
使用 "@ind_num_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