根据另一个文件中的列对文件进行排序

ola*_*ala 3 linux shell awk sed

我有两个文件格式:

loc1 num1 num2
loc2 num3 num4
Run Code Online (Sandbox Code Playgroud)

第一列是位置,我想使用第一个文件中位置的顺序对第二个文件进行排序,这样我就可以将两个文件放在一起,数字适合该位置.

我可以编写一个perl脚本来执行此操作,但我觉得可能有一些快速/简单的shell/awk命令来实现此目的.你有什么想法?

谢谢.

编辑:

这是输入,现在我实际上想要使用文件1中的第2列来排序file2.

文件1:

GID     location        NAME    GWEIGHT C1SI    M1CO    M1SI    C1LY    M1LY    C1CO    C1LI    M1LI
AID                             ARRY2X  ARRY1X  ARRY3X  ARRY4X  ARRY5X  ARRY0X  ARRY6X  ARRY7X
EWEIGHT                         1.000000        1.000000        1.000000        1.000000        1.000000        1.000000        1.000000        1.000000
GENE735X        chr17:66199278-66199496 chr17:66199278-66199496 1.000000        0.211785        -0.853890       1.071875        0.544136        0.703871     0.371880 0.218960        -2.268618
GENE1562X       chr10:80097054-80097298 chr10:80097054-80097298 1.000000        0.533673        -0.397202       0.783363        0.109824        -0.436342    0.158667 0.475748        -1.227730
GENE6579X       chr19:23694188-23694395 chr19:23694188-23694395 1.000000        0.127748        -0.203827       0.846738        0.045599        -0.211767    0.415442 0.282123        -1.302055
Run Code Online (Sandbox Code Playgroud)

文件2:

GID     location        NAME    GWEIGHT C1SI    M1CO    M1SI    C1LY    M1LY    C1CO    C1LI    M1LI
AID                             ARRY2X  ARRY1X  ARRY3X  ARRY4X  ARRY5X  ARRY0X  ARRY6X  ARRY7X
EWEIGHT                         1.000000        1.000000        1.000000        1.000000        1.000000        1.000000        1.000000        1.000000
GENE6579X       chr19:23694188-23694395 chr19:23694188-23694395 1.000000        0.127748        -0.203827       0.846738        0.045599        -0.211767    0.415442 0.282123        -1.302055
GENE735X        chr17:66199278-66199496 chr17:66199278-66199496 1.000000        0.211785        -0.853890       1.071875        0.544136        0.703871     0.371880 0.218960        -2.268618
GENE1562X       chr10:80097054-80097298 chr10:80097054-80097298 1.000000        0.533673        -0.397202       0.783363        0.109824        -0.436342    0.158667 0.475748        -1.227730
Run Code Online (Sandbox Code Playgroud)

gle*_*man 8

一个awk解决方案:将第二个文件存储在内存中,然后遍历第一个文件,从第二个文件中发出匹配的行:

awk 'FNR==NR {x2[$1] = $0; next} $1 in x2 {print x2[$1]}' second first
Run Code Online (Sandbox Code Playgroud)

实施@ Barmar的评论

join -1 2 -o "1.1 1.2 2.2 2.3" <(cat -n first | sort -k2) <(sort second) | 
sort -n | 
cut -d ' ' -f 2-
Run Code Online (Sandbox Code Playgroud)

请注意其他答案者,我测试了这些文件:

$ cat first
foo x y
bar x y
baz x y
$ cat second
bar x1 y1
baz x2 y2
foo x3 y3
Run Code Online (Sandbox Code Playgroud)

解释

awk 'FNR==NR {x2[$1] = $0; next} $1 in x2 {print x2[$1]}' second first
Run Code Online (Sandbox Code Playgroud)

此部分读取命令行参数中的第一个文件(此处为"second"):

FNR==NR {x2[$1] = $0; next}
Run Code Online (Sandbox Code Playgroud)

条件FNR == NR仅对第一个命名文件为真.FNR是awk的"文件记录号"变量,NR是来自所有输入源的当前记录号.当前行存储在x2由记录的第一个字段索引的名为(不是一个很好的变量名)的关联数组中.

下一个条件$1 in x2只会在完全读取文件"second"后才会启动.它将查看名为"first"的文件中第一行的字段,该操作将打印文件"second"中的相应行,该文件已存储在数组中.

请注意,awk命令中文件的顺序很重要.由于您根据名为"first"的文件控制输出,因此它必须是awk处理的最后一个文件.