4

我有两个格式的文件:

loc1 num1 num2
loc2 num3 num4

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

我可以编写一个 perl 脚本来做到这一点,但我觉得可能有一些快速/简单的 shell/awk 命令来实现这一点。你有什么想法?

谢谢。

编辑:

这是输入,现在我实际上想使用文件 1 中的第 2 列对文件 2 进行排序。

文件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

文件 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
4

2 回答 2

10

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

awk 'FNR==NR {x2[$1] = $0; next} $1 in x2 {print x2[$1]}' second first

实施@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-

请注意其他回答者,我使用这些文件进行了测试:

$ cat first
foo x y
bar x y
baz x y
$ cat second
bar x1 y1
baz x2 y2
foo x3 y3

的解释

awk 'FNR==NR {x2[$1] = $0; next} $1 in x2 {print x2[$1]}' second first

这部分读取命令行参数中的第一个文件(此处为“第二个”):

FNR==NR {x2[$1] = $0; next}

该条件FNR == NR仅适用于第一个命名文件。FNR是 awk 的“文件记录号”变量,NR是来自所有输入源的当前记录号。当前行存储在x2由记录的第一个字段索引的名为(不是一个大变量名)的关联数组中。

下一个条件 ,$1 in x2只会在文件 "second" 被完全读取后开始。它将查看名为“first”的文件中行的第一个字段,并且该操作打印文件“second”中的相应行,该文件已存储在数组中。

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

于 2013-04-29T17:53:49.883 回答
0

使用该paste命令合并两个文件的行。例如:

文件1:

f1_11   f1_12         
f1_21   f1_22         
f1_31   f1_32         
f1_41   f1_42     

文件2:

f2_11   f2_12         
f2_21   f2_22         
f2_31   f2_32         
f2_41   f2_42

➜ ~ paste file1 file2

f1_11   f1_12           f2_11   f2_12         
f1_21   f1_22           f2_21   f2_22         
f1_31   f1_32           f2_31   f2_32         
f1_41   f1_42           f2_41   f2_42   

现在您可以对第 1 列进行排序。

paste file1 file2 | sort -k1,1

最后但同样重要的是,如果您不想在最终输出中看到 file1 的数据,请删除属于第二个文件的列:

paste file1 file2 | sort -k1,1 | cut -f4-6
于 2013-04-29T18:23:04.117 回答