【问题标题】:sort a file based on a column in another file根据另一个文件中的列对文件进行排序
【发布时间】:2013-04-29 17:20:19
【问题描述】:

我有两个格式的文件:

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

【问题讨论】:

  • 如果您需要帮助,您需要添加一些有代表性的输入。
  • 为什么不对两个文件进行排序?然后你就可以使用join命令了。
  • 你可以在第一个文件上运行cat -n,然后在第二个文件上运行join,然后按cat -n打印的行号对它们进行排序。
  • 我希望两个文件都按第一个文件中第一列的顺序排列

标签: linux shell sed awk


【解决方案1】:

一个 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处理的last文件。

【讨论】:

  • 你能解释一下 awk 命令吗?具体来说,x2[$1]=$0?
  • 添加了解释。希望有帮助
  • 需要比“不起作用”更多的细节。你到底输入了什么?你到底看到了什么?
  • 我刚刚创建了两个与您的“第一”和“第二”相同的文件。然后尝试了您的命令,顺便说一句,这些文件是制表符分隔的,也许这就是原因?
  • 糟糕,我的错误。而不是$1 in line,它应该是$1 in x2。我按答案编辑以解决此问题。
【解决方案2】:

使用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

【讨论】:

  • 这不是我真正想要的... f1_11, f1_21.. 和 f2_11, f2_21.. 在我的情况下是一样的。所以粘贴会搞砸
  • 那么问题是您的文件没有您最初所说的列。粘贴也可以完美地在相等的行上工作。您必须正确地对输入文件进行排序,并首先将内容排序到定义明确的列中。
猜你喜欢
  • 1970-01-01
  • 2012-02-26
  • 2014-12-02
  • 2015-09-07
  • 2016-04-08
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多