如何使用awk按列的最后一个值对列进行排序?

时间:2013-08-29 16:06:17

标签: bash sorting awk

我有一个这样的文件(有数百行和列)

1  2 3
4  5 6
7 88 9

我希望根据最后一行值(或特定行值)重新排序列

1 3 2
4 6 5
7 9 88

如何使用awk(或其他)来完成此任务? 提前感谢您的帮助

编辑:我要感谢大家,如果我不够清楚,我要道歉。 我想做的是:

  • 取一条线(例如最后一条);
  • 使用所选行的排序值对矩阵的列重新排序,以便对订单进行验证。

因此,最后一行是7 88 9,其排序为7 9 88,然后必须以这样的方式对三列进行重新排序,在这种情况下,最后两列是交换的。< / p>


一个四列更通用的例子,再次基于最后一行:

输入:

1    2 3  4
4    5 6  7
7 88.0 9 -3

输出:

 4 1 3 2
 7 4 6 5
-3 7 9 88.0

3 个答案:

答案 0 :(得分:1)

这是一个快速,肮脏和可改进的解决方案:(编辑,因为OP澄清了数字是浮点数)。

$ cat test.dat
1 2 3
4 5 6
.07 .88 -.09
$ awk "{print $(printf '$%d%.0s\n' \
                  $(i=0; for x in $(tail -n1 test.dat); do
                           echo $((++i)) $x
                         done |
                  sort -k2g) | paste -sd,)}" test.dat
3 1 2
6 4 5
-.09 .07 .88

要了解那里发生了什么(或者至少是其中的一部分):

$ echo "{print $(printf '$%d%.0s\n' \
                      $(i=0; for x in $(tail -n1 test.dat); do
                               echo $((++i)) $x
                             done |
                      sort -k2g) | paste -sd,)}" test.dat
{print $3,$1,$2} test.dat

要使其适用于任意行,请将tail -n1替换为tail -n+$L|head -n1

答案 1 :(得分:1)

使用GNU awk的数组排序功能可以很好地解决这个问题。 GNU awk允许您使用PROCINFO控制数组遍历。因此需要文件的两次传递,第一次传递将最后一条记录拆分为数组,第二次传递以值顺序循环遍历数组的索引,并根据索引输出字段。下面的代码可能比我更好地解释了它。

awk 'BEGIN{PROCINFO["sorted_in"] = "@val_num_asc"};
    NR == FNR {for (x in arr) delete arr[x]; split($0, arr)};
    NR != FNR{sep=""; for (x in arr) {printf sep""$x; sep=" "} print ""}' file.txt file.txt
4 1 3 2
7 4 6 5
-3 7 9 88.0

答案 2 :(得分:0)

更新

创建一个名为transpose.awk的文件,如下所示:

{ 
    for (i=1; i<=NF; i++)  {
        a[NR,i] = $i
    }
}
NF>p { p = NF }
END {    
    for(j=1; j<=p; j++) {
        str=a[1,j]
        for(i=2; i<=NR; i++){
            str=str OFS a[i,j];
        }
        print str
    }
}

现在这里的脚本应该适合你:

awk -f transpose.awk file | sort -n -k $(awk 'NR==1{print NF}' file) | awk -f transpose.awk
1 3 2
4 6 5
7 9 88

我在这里两次使用transpose.awk。一旦将行转换为列,然后我按最后一列进行数字排序,然后再次将行转换为列。它可能不是最有效的解决方案,但它符合OP的要求。

转换awk脚本提供:来自An efficient way to transpose a file in Bash的@ ghostdog74