在Python中对文件使用grep

在Python中对文件使用grep,python,Python,我已经在这里搜索了grep答案,但找不到答案。它们似乎都在搜索文件中的字符串,而不是文件中的字符串列表。我已经有了一个搜索功能,但grep做得更快。我在sn.txt文件中有一个字符串列表,每行有一个字符串,没有删除器。我想在另一个文件Merge_EXP.EXP中搜索具有匹配项的行,并将其写入新文件。我正在搜索的文件有50万行,因此在没有grep的情况下搜索几千行需要几个小时 当我在windows的命令提示符下运行它时,它会在几分钟内完成: grep --file=sn.txt Merge_EXP

我已经在这里搜索了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)

以下是纯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
merge_exp.exp:

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


试试这个,看看需要多长时间…

当我使用grep位置的完整路径时,我将grep\u loc、Serial\u 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"

我认为您没有为您的问题选择正确的标题:您想要做的是等效于数据库连接。您可以在这个特定的实例中使用grep,因为您的一个文件只有密钥,没有其他信息。然而,我认为这是可能的,但我当然不知道你的情况下,在未来你的sn.txt也可能包含额外的信息

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

将所有数据导入数据库,然后在sql或等效程序中执行左连接 使用python大型数据工具 对于后者,您可以尝试或推荐,因为您正在使用字符串。熊猫有一个优化的合并程序,根据我的经验,在引擎盖下使用cython非常快

下面是解决您的问题的伪代码。它接近真实代码,但我需要知道您要匹配的列的名称。这里我假设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")

如果你有一个工作的grep,为什么需要python?你的输入文件是什么样子的?os.systemgrep-file=sn.txt Merge\u EXP.EXP>Merge\u EXP\u Out.EXP这个python可以改进很多。如果你给我文件的输入格式,我可以给你更好的输出。这有帮助吗?我真的让它起作用了。问题是,如果没有grep的完整路径,它将失败。如果在grep.exe位置之外的命令行中运行,则会出现正则表达式过长错误。Python没有给你这个。一旦我进入grep的完整路径,它就非常有效:
# 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")