Sorting AWK——如何进行选择性多列排序?
在awk中,我如何做到这一点: 输入:Sorting AWK——如何进行选择性多列排序?,sorting,awk,multiple-columns,Sorting,Awk,Multiple Columns,在awk中,我如何做到这一点: 输入: 1 a f 1 12 v 2 b g 2 10 w 3 c h 3 19 x 4 d i 4 15 y 5 e j 5 11 z 所需输出,通过将数值排序为$5: 1 a f 2 10 w 2 b g 5 11 z 3 c h 1 12 v 4 d i 4 15 y 5 e j 3 19 x 注意排序只应影响$4、
1 a f 1 12 v
2 b g 2 10 w
3 c h 3 19 x
4 d i 4 15 y
5 e j 5 11 z
所需输出,通过将数值排序为$5
:
1 a f 2 10 w
2 b g 5 11 z
3 c h 1 12 v
4 d i 4 15 y
5 e j 3 19 x
注意排序只应影响
$4
、$5
和$6
(基于$5
的值),其中表的前一部分保持不变。这可以通过以下步骤完成:
就我个人而言,我发现使用
awk
对列数组进行安全排序相当棘手,因为通常需要按住重复键进行排序。如果您需要有选择地对一组列进行排序,我将调用paste
以获得一些帮助:
paste -d ' ' <(awk '{ print $1, $2, $3 }' file.txt) <(awk '{ print $4, $5, $6 | "sort -k 2" }' file.txt)
这可以在纯awk
中完成,但正如@steve所说,这并不理想gawk
具有有限的排序功能,而awk
根本没有内置排序功能。也就是说,这里有一个(相当粗俗)的解决方案,它使用了gawk
中的比较函数:
[ghoti@pc ~/tmp3]$ cat text
1 a f 1 12 v
2 b g 2 10 w
3 c h 3 19 x
4 d i 4 15 y
5 e j 5 11 z
[ghoti@pc ~/tmp3]$ cat doit.gawk
### Function to be called by asort().
function cmp(i1,v1,i2,v2) {
split(v1,a1); split(v2,a2);
if (a1[2]>a2[2]) { return 1; }
else if (a1[2]<a2[2]) { return -1; }
else { return 0; }
}
### Left-hand-side and right-hand-side, are sorted differently.
{
lhs[NR]=sprintf("%s %s %s",$1,$2,$3);
rhs[NR]=sprintf("%s %s %s",$4,$5,$6);
}
END {
asort(rhs,sorted,"cmp"); ### This calls the function we defined, above.
for (i=1;i<=NR;i++) { ### Step through the arrays and reassemble.
printf("%s %s\n",lhs[i],sorted[i]);
}
}
[ghoti@pc ~/tmp3]$ gawk -f doit.gawk text
1 a f 2 10 w
2 b g 5 11 z
3 c h 1 12 v
4 d i 4 15 y
5 e j 3 19 x
[ghoti@pc ~/tmp3]$
[ghoti@pc~/tmp3]$cat文本
1安f 1 12伏
2B210W
3CH319X
4 d i 4 15 y
5 e j 5 11 z
[ghoti@pc~/tmp3]$cat doit.gawk
###要由asort()调用的函数。
功能cmp(i1、v1、i2、v2){
分割(v1,a1);分割(v2,a2);
如果(a1[2]>a2[2]){返回1;}
否则,如果(a1[2]您是指列$4
、$5
和$6
?AWK从1:)您是对的。这是一个打字错误。感谢您的更正和解决方案!您是否有任何不调用外部函数的其他解决方案的想法?只是想知道这是否可能(但执行起来可能太复杂)排序
和粘贴
不是“外部功能”,而是基本的Unix工具。它们允许您构建非常灵活的解决方案。当原始文件的第5列的数字大于19且小于10时,这不起作用。我曾尝试仅使用GNU awk
来执行此操作,但大约20分钟后我放弃了。我知道这不是强加的ble+1
1 a f 2 10 w
2 b g 5 11 z
3 c h 1 12 v
4 d i 4 15 y
5 e j 3 19 x
[ghoti@pc ~/tmp3]$ cat text
1 a f 1 12 v
2 b g 2 10 w
3 c h 3 19 x
4 d i 4 15 y
5 e j 5 11 z
[ghoti@pc ~/tmp3]$ cat doit.gawk
### Function to be called by asort().
function cmp(i1,v1,i2,v2) {
split(v1,a1); split(v2,a2);
if (a1[2]>a2[2]) { return 1; }
else if (a1[2]<a2[2]) { return -1; }
else { return 0; }
}
### Left-hand-side and right-hand-side, are sorted differently.
{
lhs[NR]=sprintf("%s %s %s",$1,$2,$3);
rhs[NR]=sprintf("%s %s %s",$4,$5,$6);
}
END {
asort(rhs,sorted,"cmp"); ### This calls the function we defined, above.
for (i=1;i<=NR;i++) { ### Step through the arrays and reassemble.
printf("%s %s\n",lhs[i],sorted[i]);
}
}
[ghoti@pc ~/tmp3]$ gawk -f doit.gawk text
1 a f 2 10 w
2 b g 5 11 z
3 c h 1 12 v
4 d i 4 15 y
5 e j 3 19 x
[ghoti@pc ~/tmp3]$