如何根据第一行对列进行排序?

LLV*_*rdo 12 awk text-processing

我需要对一个非常大的数据集(1000 行和 700000 列)的列进行排序。例如,我的列是随机排列的,如:col1 col4 col3 col2,我需要对其进行排序。

我一直在尝试一些命令,但没有成功。

例子:

ID M2 M5 M8 M1 M3 M9 .....M7000000
Animal1 1 0 2 1 0 2 .....1
Animal2 0 1 2 0 1 1 .....0
Animal3 2 1 0 1 2 1 .....0
.
.
.
.
Animaln
Run Code Online (Sandbox Code Playgroud)

在这个例子中,点表示我有很多列和行。同样,我需要对列进行排序,如下所示:

ID M1 M2 M3 M4 M5 M6 .....M7000000
Animal1 1 0 2 1 0 2 .....1
Animal2 0 1 2 0 1 1 .....0
Animal3 2 1 0 1 2 1 .....0
.
.
.
.
Animaln
Run Code Online (Sandbox Code Playgroud)

谢谢

Sat*_*ura 10

使用 GNUdatamash和 GNU sort

datamash transpose -t ' ' -H <file_in.csv | sort -V | datamash transpose -t ' ' -H >file_out.csv
Run Code Online (Sandbox Code Playgroud)

这适用于“相当小”的数据。它可能适用于您的文件,也可能不适用于您的文件。

编辑:下面没有换位的解决方案应该占用较少的资源。

  • FWIW,`rs`(“重塑数据数组”)在一些 BSD 的基本系统中可用。 (2认同)

小智 6

perl -pale '
   $. == 1 and
   @I = map  { $_->[1] }
        sort { $a->[0] <=> $b->[0] }
        map  { [ $F[$_] =~ /^M(\d+)$/, $_ ] } 1..$#F;
   $_ = "@F[0, @I]";
' yourlargefile
Run Code Online (Sandbox Code Playgroud)
  1. 对于第一行,我们M使用众所周知的Schwartzian maneuver. 这为我们提供了重新排序的索引,以便列按数字排序(M1,M2,M3,...)
  2. 剩下的就是使用来自的这些索引来@I重新排列@F元素。
  3. 以双引号形式分配数组会将其转换为元素空格分隔的字符串。
  4. -pPerl 的选项启用$_内容的自动打印,-l应添加newline.


gle*_*man 6

使用 perl 模块 Sort::Naturally

输入数据

ID M2 M5 M8 M1 M3 M9 M700000
A1 m1,2 m1,5 m1,8 m1,1 m1,3 m1,9 m1,7000000
A2 m2,2 m2,5 m2,8 m2,1 m2,3 m2,9 m2,7000000
A3 m3,2 m3,5 m3,8 m3,1 m3,3 m3,9 m3,7000000
A1000 m1000,2 m1000,5 m1000,8 m1000,1 m1000,3 m1000,9 m1000,7000000
Run Code Online (Sandbox Code Playgroud)
ID M2 M5 M8 M1 M3 M9 M700000
A1 m1,2 m1,5 m1,8 m1,1 m1,3 m1,9 m1,7000000
A2 m2,2 m2,5 m2,8 m2,1 m2,3 m2,9 m2,7000000
A3 m3,2 m3,5 m3,8 m3,1 m3,3 m3,9 m3,7000000
A1000 m1000,2 m1000,5 m1000,8 m1000,1 m1000,3 m1000,9 m1000,7000000
Run Code Online (Sandbox Code Playgroud)

输出

ID M1 M2 M3 M5 M8 M9 M700000
A1 m1,1 m1,2 m1,3 m1,5 m1,8 m1,9 m1,7000000
A2 m2,1 m2,2 m2,3 m2,5 m2,8 m2,9 m2,7000000
A3 m3,1 m3,2 m3,3 m3,5 m3,8 m3,9 m3,7000000
A1000 m1000,1 m1000,2 m1000,3 m1000,5 m1000,8 m1000,9 m1000,7000000
Run Code Online (Sandbox Code Playgroud)