对多列进行排序

对多列进行排序

我有一个文件,其内容如下所示:

19.58 1925 Alpha
20.40 1924 Otter
13.66 1920 Gold

我试图“按列”对其进行排序以输出以下内容:

13.40 1920 Alpha
19.58 1924 Gold
20.66 1925 Otter

我尝试过各种代码组合,例如:

cat files | sort -t. -k1,1n | sort -t " " -k2,2n -k3,3r k4,4n

但这不会输出想要的结果。我怎样才能实现我提到的排序?

答案1

printf "%s.%s %s %s\n" $(paste <(awk -F'[. ]' '{print $1}' file | sort -n) <(awk -F'[. ]' '{print $2}' file | sort -n) <(awk -F'[. ]' '{print $3}' file | sort -n) <(awk -F'[. ]' '{print $4}' file | sort))

输出:

1920 年 13.40 阿尔法
19.58 1924 黄金
20.66 1925 水獭

答案2

如果你有 GNU awk,那么可以通过特殊数组的一点帮助来完成排序PROCINFO

awk -F '[. ]' '{for(i=1;i<NF+1;i++) a[i][NR]=$i} \
    END{PROCINFO["sorted_in"]="@val_num_asc"; \
        for(j=1;j<NF+1;j++){ I=0; for(i in a[j]) A[++I][j]=a[j][i]} \
            for(i=1;i<NR+1;i++){ printf A[i][1]"."; \
                for(j=2;j<NF+1;j++) printf A[i][j]" "; printf "\n"}}' file

上面的代码乍一看可能很复杂,但实际上非常简单 - 它只是将整个文件存储在 array 中a,最后根据A需要将其诉诸 array 。主要技巧是@val_num_asc当我们想要按数字升序对列进行排序时使用。

它应该适用于任意数量的行和列,只需记住整个文件存储在内存中,因此对于大型表来说可能会很慢。

答案3

#!/bin/sh

for i in 1 2 3 4
do
    tr . " " < "${1:?}" | cut -d' ' -f$i | sort > $$-$i
done

paste -d. $$-[12] | paste -d' ' - $$-[34]

rm $$-[1234]

相关内容