从两个文件的特定列中查找匹配项

2024-06-01 14:11:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个不同长度的文件,但都有3个制表符分隔的列。File2的行数为5000000000,File1的行数为2000000:

文件1:

abc foo bar
lmn potato rst
lmp tomato  asd

文件2:

123 asdasc  dad
032 foo 2134
123 linkin  9123
42  cads    asd
45654   tomato  12123

我需要使用第二列作为匹配两个文件的键,如果第二列上有匹配项,则从File1和File2提取行

fout = open('outfile', 'w')
with open('file1', 'r') as f1, open('file2', 'r') as f2:
  file2_keys = [i.split('\t')[1] for i in f2]
  for line in f1:
    if line.split('\t')[1] in file2_keys:
      print>>fout, line

但这只给了我文件1中的一行。你知道吗

所需输出应为

排水口2:

032 foo 2134
45654   tomato  12123

排水口1:

abc foo bar
lmp tomato  asd

在unix中有没有一种有效的方法?如何才能有效地做到这一点?你知道吗


Tags: 文件infooaslinebaropenfile1
3条回答

Is there a way to do it in unix effectively?

你可以利用awk。你知道吗

awk 'NR==FNR{a[$2]=$2;next}{if ($2 in a) {print $0}}' File1 File2

将从File1生成所需的输出:

032 foo 2134
45654   tomato 12123

同样地

awk 'NR==FNR{a[$2]=$2;next}{if ($2 in a) {print $0}}' File2 File1

将从File2产生所需的输出:

abc foo bar
lmp tomato  asd

有效地?使用0xDeDeBrad建议的^ {CD1>}或坚持C++:

#include <iostream>
#include <fstream>
#include <set>

int main() {

    std::string a, b, c;
    std::set<std::string> s;

    std::ifstream file1("File1");
    while (file1 >> a >> b >> c)
        s.insert(b);

    std::ifstream file2("File2");
    while (file2 >> a >> b >> c)
        if (s.count(b) != 0)
            std::cout << a << "\t" << b << "\t" << c << std::endl;

}

输出

032 foo 2134
45654   tomato  12123

由于您添加了一个python标记并在python中进行了尝试,下面是python的实现:

fout1 = open('outfile1', 'w')
fout2 = open('outfile2', 'w')
with open('file1') as f1, open('file2') as f2:
    file2_lines = [i.strip() for i in f2]
    file2_keys = [i.split(' ')[1] for i in file2_lines]
    d = dict(zip(file2_keys, file2_lines))
    for line in f1:
        k = line.split(' ')[1]
        if k in d:
            print >>fout1, line.strip()
            print >>fout2, d[k]
fout1.close()
fout2.close()

相关问题 更多 >