1

我在这里搜索了 grep 答案,但找不到答案。他们似乎都在文件中搜索字符串,而不是文件中的字符串列表。我已经有一个可以工作的搜索功能,但是 grep 做得更快。我在文件 sn.txt 中有一个字符串列表(每行一个字符串,没有分隔符)。我想在另一个文件 (Merge_EXP.exp) 中搜索匹配的行并将其写入新文件。我正在搜索的文件有 50 万行,因此在没有 grep 的情况下在那里搜索几千行需要几个小时。

当我在 Windows 中从命令提示符运行它时,它会在几分钟内完成:

grep --file=sn.txt Merge_EXP.exp > Merge_EXP_Out.exp

如何从 Python 调用相同的过程?我真的不想要 Python 中的替代品,因为我已经有了一个可以使用但需要一段时间的替代品。除非你认为你可以显着提高性能:

def match_SN(serialnumb, Exp_Merge, output_exp):
    fout = open(output_exp,'a')
    f = open(Exp_Merge,'r')
    # skip first line
    f.readline()
    for record in f:
        record = record.strip().rstrip('\n')
        if serialnumb in record:
            fout.write (record + '\n')
    f.close()
    fout.close()

def main(Output_CSV, Exp_Merge, updated_exp):

    # create a blank output
    fout = open(updated_exp,'w')

    # copy header records
    f = open(Exp_Merge,'r')
    header1 = f.readline()
    fout.write(header1)
    header2 = f.readline()
    fout.write(header2)
    fout.close()
    f.close()

    f_csv = open(Output_CSV,'r')
    f_csv.readline()
    for rec in f_csv:
        rec_list = rec.split(",")
        sn = rec_list[2]
        sn = sn.strip().rstrip('\n')
        match_SN(sn,Exp_Merge,updated_exp)
4

3 回答 3

0

这是纯python代码的优化版本:

def main(Output_CSV, Exp_Merge, updated_exp):
    output_list = []

    # copy header records
    records = open(Exp_Merge,'r').readlines()
    output_list = records[0:2]

    serials = open(Output_CSV,'r').readlines()
    serials = [x.split(",")[2].strip().rstrip('\n') for x in serials]

    for s in serials:
        items = [x for x in records if s in x]
        output_list.extend(items)

    open(updated_exp, "w").write("".join(output_list))

main("sn.txt", "merge_exp.exp", "outx.txt")

输入

sn.txt:

x,y,0011
x,y,0002

合并exp.exp:

Header1
Header2
0011abc
0011bcd
5000n
5600m
6530j
0034k
2000lg
0002gg

输出

Header1
Header2
0011abc
0011bcd
0002gg

试试这个,看看需要多少时间......

于 2013-02-22T14:37:38.773 回答
0

当我使用 grep 位置的完整路径时,它起作用了(我将 grep_loc、Serial_List、Export 传递给它):

import os

Export_Dir = os.path.dirname(Export)
Export_Name = os.path.basename(Export)

Output = Export_Dir + "\Output_" + Export_Name
print "\nOutput: " + Output + "\n"

cmd = grep_loc + " --file=" + Serial_List + " " + Export + " > " + Output
print "grep usage: \n" + cmd + "\n"
os.system(cmd)
print "Output created\n"
于 2013-02-25T17:52:42.260 回答
0

我认为您没有为您的问题选择正确的标题:您想要做的是相当于数据库 JOIN。在此特定情况下,您可以使用 grep,因为您的一个文件只有键,没有其他信息。但是,我认为将来您的 sn.txt 很可能(但当然我不知道您的情况)也可能包含额外信息。

所以我会解决一般情况。有多种解决方案:

  • 将所有数据导入数据库,然后执行 LEFT JOIN (in sql) 或等效操作
  • 使用python大数据工具

对于后者,您可以尝试numpy或者推荐因为您正在使用字符串pandas。Pandas 有一个优化的合并例程,根据我的经验,它非常快(在引擎盖下使用 cython)。

这是解决您问题的 pandas PSEUDO 代码。它接近真实代码,但我需要知道要匹配的列的名称。我假设这里的一列sn.txt被调用key,而匹配的列merge_txt被调用sn。我还看到您在 merge_exp 中有两个标题行,请阅读文档。

# PSEUDO CODE (but close)
import pandas
left = pandas.read_csv('sn.txt')
right = pandas.read_csv('merge_exp.exp')
out = pandas.merge(left, right, left_on="key", right_on="sn", how='left')
out.to_csv("outx.txt")
于 2013-10-08T07:07:39.117 回答