比较两个文件中的数据,一个有 2 列,另一个有 3 列

比较两个文件中的数据,一个有 2 列,另一个有 3 列

我有两个文件:

文件一:

Chromosome   Position
Chr1    5242097
Chr1    4876397
Chr1    9474943
Chr1    8494518
Chr1    39872693
Chr1    9445153
Chr1    23044399
Chr1    8018859
Chr1    9474943
Chr1    42380010
Chr1    9474943
Chr1    22677151
Chr1    23044399
Chr1    42380010

文件2:

Chr1    1   0
Chr1    2   0
Chr1    3   0
Chr1    4   0
Chr1    5   0
Chr1    6   0
Chr1    7   0
Chr1    8   0
Chr1    9   0
Chr1    10  0
Chr1    11  0
Chr1    12  0
Chr1    13  0
Chr1    14  0
Chr1    15  0
Chr1    16  0
Chr1    17  0
Chr1    18  0
Chr1    19  0
Chr1    20  0
Chr1    21  0
Chr1    22  0
Chr1    23  0
Chr1    24  0
Chr1    25  0
Chr1    26  0
Chr1    27  0
Chr1    28  0
Chr1    29  0
Chr1    30  0
Chr1    31  0
Chr1    32  0
Chr1    33  0
Chr1    34  0
Chr1    35  0
Chr1    36  0
Chr1    37  0
Chr1    38  0
Chr1    39  0
Chr1    40  0
Chr1    41  0
Chr1    42  0
Chr1    43  0
Chr1    44  0
Chr1    45  0
Chr1    46  0
Chr1    47  0
Chr1    48  0
Chr1    49  0
Chr1    50  0

File2 非常大,所以我没有展示整个内容。这些数字可以上升到 6 位以上。

我想从 file2 中获取第三列(如果它与 file1 的第二列匹配)。

我写了一个 Perl 程序,但是速度很慢。我正在寻找一种快速的方法来做到这一点。 Grep 也很慢。

答案1

我会写

awk '
    # store column 2 from the first file
    NR == FNR {pos[$2] = 1; next}

    # from the second file, print the 3rd field if it occurred in file1
    $3 in pos {print $3}
' file1 file2

答案2

仅保留文件 1 中的 col2

awk '{print $2}' file1 > file1_col2

然后保留 file2 中的 col3:

awk '{print $3}'  file2> file2_col3

现在搜索 file2_col3 中出现的 file1_col2 行:

grep -f file1_col2 file2_col3

答案3

如果速度慢,C++ 应该会有所帮助,说真的,它也可以用来编写快速的东西 =)。保存到file.cc并编译,在file目录下g++ file.cc -O2 -o file运行;将第二个./file替换firstfilename为编译前所需的文件名。

你将无法在速度上击败 C++ =)

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
   ifstream f1("firstfilename"), f2("secondfilename");
   string s;
   int i1, i2, line=0;
   while (!f1.eof()) {
      line++;
      if (f2.eof()) {
         cout << "Length different!" << "\n";
      }
      f1>>s>>i1;
      f2>>s>>i2>>i2;
      if (i1 != i2) {
         cout << "Not matching line " << line << " " << i1 << "<>" << i2 << "\n";
      }
   }
}

答案4

使用join, 包括sort如果您的数据未按适当的字段排序。

join -1 2 -2 3 -o 2.3 <(sort -k2,2 file1) <(sort -k3,3 file2)

如果sort不需要:

join -1 2 -2 3 -o 2.3 file1 file2

这是使用 GNU 实用程序。对于其他变体,我需要知道你正在使用什么 Unix。上面的版本sort显示了 Bash 进程替换,它也适用于其他一些 shell。

由于连接字段也是输出字段,因此-o 2.3可以简化为-o 0

相关内容