如何以列方式对一组数据进行排序?

时间:2018-03-09 01:15:03

标签: linux bash perl awk

我有一组数据,如附加的原始数据,当我按排序-n 对原始数据进行排序时,数据逐行排序,输出看起来像这样:

 3  6  9  22
 2  3  4  5
 1  7  16 20

我想以列方式对数据进行排序,输出如下所示:

 1  2  4  3
 3  6  9  16
 5  7  20 22

好的,我确实尝试过。

我的主要理想是按列提取数据,然后对其进行排序然后粘贴,但我无法通过。这是我的剧本:

for ((i=1; i<=4; i=i+1)) 
do 
     awk '{print $i}' file | sort -n >>output
done

输出:

1  7  20 16
3  6  9  22
5  2  4  3
1  7  20 16
3  6  9  22
5  2  4  3
1  7  20 16
3  6  9  22
5  2  4  3
1  7  20 16
3  6  9  22
5  2  4  3

似乎 $ i 不可更改且等于$ 0

非常感谢。

 raw data1

 3  6  9  22
 5  2  4  3
 1  7  20 16

raw data2

488.000000 1236.000000 984.000000 2388.000000 788.000000 704.000000
600.000000 1348.000000 872.000000 2500.000000 900.000000 816.000000
232.000000 516.000000 1704.000000 1668.000000 68.000000 16.000000
244.000000 504.000000 1716.000000 1656.000000 56.000000 28.000000
2340.000000 3088.000000 868.000000 4240.000000 2640.000000 2556.000000
2588.000000 3336.000000 1116.000000 4488.000000 2888.000000 2804.000000

2 个答案:

答案 0 :(得分:0)

awk救援!!

awk '{f1[NR]=$1; f2[NR]=$2; f3[NR]=$3; f4[NR]=$4} 
  END{asort(f1); asort(f2); asort(f3); asort(f4); 
      for(i=1;i<=NR;i++) print f1[i],f2[i],f3[i],f4[i]}' file

1 2 4 3
3 6 9 16
5 7 20 22

可能还有一种更聪明的方法......

答案 1 :(得分:0)

让我介绍一个使用cutsort的灵活解决方案,您可以在任何M,N尺寸制表符分隔的输入矩阵上使用。

$ cat -vTE data_to_sort.in 
3^I6^I9^I22$
5^I2^I4^I3$
1^I7^I20^I16$

$ col=4; line=3; 
$ for i in $(seq ${col}); do cut -f$i data_to_sort.in |\
> sort -n; done | paste $(for i in $(seq ${line}); do echo -n "- "; done) |\
> datamash transpose
1       2       4       3
3       6       9       16
5       7       20      22

如果输入文件不是\t分隔符,则需要定义正确的分隔符以使用-d"$DELIM_CHAR"使剪切正常工作。

  • for i in $(seq ${col}); do cut -f$i data_to_sort.in | sort -n; done会将文件的每一列分开并对其进行排序
  • paste $(for i in $(seq ${line}); do echo -n "- "; done)粘贴列将重新创建矩阵结构
  • 转换中间矩阵需要
  • datamash transpose

感谢 Sundeep 的反馈,让我向您介绍一个更好的解决方案,使用pr代替paste命令来生成列:

$ col=4; line=3 
$ for i in $(seq ${col}); do cut -f$i data_to_sort.in |\
> sort -n; done | pr -${line}ats | datamash transpose

最后但并非最不重要的,

$ col=4; for i in $(seq ${col}); do cut -f$i data_to_sort.in |\
> sort -n; done | pr -${col}ts                                                    
1       2       4       3
3       6       9       16
5       7       20      22

以下解决方案将允许我们完全不使用datamash !!!

(非常感谢 Sundeep

对怀疑论者和贬低者有效的证据......

Proof that is working for the skeptics...

第二轮,包含6列:

$ col=6; for i in $(seq ${col}); do cut -f$i <(sed 's/^ \+//g;s/ \+/\t/g' data2) | sort -n; done | pr -${col}ts | tr '\t' '  '                 
232.000000 504.000000 868.000000 1656.000000 56.000000 16.000000
244.000000 516.000000 872.000000 1668.000000 68.000000 28.000000
488.000000 1236.000000 984.000000 2388.000000 788.000000 704.000000
600.000000 1348.000000 1116.000000 2500.000000 900.000000 816.000000
2340.000000 3088.000000 1704.000000 4240.000000 2640.000000 2556.000000
2588.000000 3336.000000 1716.000000 4488.000000 2888.000000 2804.000000

enter image description here