在txt文件中搜索多个列中的多个名称

时间:2018-11-08 03:14:49

标签: python

我正在尝试在txt文件的前两列中扫描某些文件名。如果我在txt文件中找到带有文件名的一行,我想在txt文件中打印该行。例如,我要查找的文件名是

File1 
File2
File3
File4 

我要扫描这些文件名的txt文件如下所示:

File23 File65
File1 File32
File45 File2
File12 Fil67
File3 File99

我想要的输出看起来像这样(只在行中保留我要查找的文件名:

File1 File32
File45 File2
File3 File99

这是我目前正在尝试使用的代码,但是我没有得到任何输出:

newcatalog = open(dir+'newS34catalog.txt', "r")
searchlinesnew = newcatalog.readlines()
newcatalog.close()

files = open(dir+'filesiwanttofind.txt',"r")
searchfiles = files.readline()
for i, line in enumerate(searchlinesnew):
    if searchfiles in line:
        for l in searchlinesnew[i:i+3]:
            print(l,)

6 个答案:

答案 0 :(得分:1)

这是可行的方法,并且避免了将所有文件读入内存,因为所有内容都是逐行处理的:

with open(dir+'filesiwanttofind.txt', "r") as wanted:
    wantedfiles = [line.strip() for line in wanted]

with open(dir+'newS34catalog.txt', "r") as newcatalog:
    for line in newcatalog:
        if any(wanted in line.split() for wanted in wantedfiles):
            print(line.rstrip())

输出:

File1 File32
File45 File2
File3 File99

答案 1 :(得分:0)

在不知道文件内容和预期(期望)输出的情况下很难确定地说,但是检查searchfiles in line似乎是错误的:您正在检查从filesiwanttofind.txt读取的字符串是否是文件的子字符串。您正在查看的行,我怀疑这不是您的意图。

答案 2 :(得分:0)

如果文件的内容是固定的,并且始终为File1,则...可能就是您所需要的。假设将每一行文件读入x, y list

x = ["File1", "File2", "File3", "File4"]

y = ["File23 File65", "File1 File32","File45 File2", "File12 File67", "File3 File99"]

y = [item.strip().split(" ") for item in y]  # turn it into list for searching

results = []
for filename in x:
    for searchstr in y:
        if filename in searchstr:
            results.append(searchstr)

print(results)
# result: [['File1', 'File32'], ['File45', 'File2'], ['File3', 'File99']]

答案 3 :(得分:0)

您可以将要查找的文件名存储在一组中,以进行快速(O(1))查找。

然后,您可以逐行从文件中读取文件,在一个空格上分割,然后检查分割后产生的文件是否在集合中。如果是这样,请打印该行。代码如下所示

filename = dir+'newS34catalog.txt'
newcatalog = open(filename, 'r')
lookup_table = {"File1", "File2", "File3", "File4"}

for line in newcatalog:
    filenames = line.split(" ")
    if filenames[0] in lookup_table or filenames[1] in lookup_table:
        print line # you can also append to a results tuple or lists depending on your required output.

我希望代码是可以理解的。

答案 4 :(得分:0)

我试图使您的代码正常工作,同时进行尽可能少的更改。我还解释了我所做的一些更改,以便您可以更好地理解它。

searchfiles = files.read().splitlines()

files.readline()仅读取第一行。虽然您可以使用files.readlines(),但会在每行末尾提供换行符

if any(s in line.split() for s in searchfiles):

在您的初始代码中,searchfiles变量是一行,现在它是行列表。如果您要搜索的字符串不在第一列中,我们会将line变量拆分为一个列表

完整的解决方案出来了

newcatalog = open('newS34catalog.txt', "r")
searchlinesnew = newcatalog.readlines()
newcatalog.close()

files = open('filesiwanttofind.txt',"r")
searchfiles = files.read().splitlines()
for i, line in enumerate(searchlinesnew):
    if any(s in line.split() for s in searchfiles):
        print(line, end="")

我本打算编写一个更有效的解决方案,但是Martineau编写了比我想象的要好的得多的解决方案。 因此,我将在此处将其添加为一个完整的答案。

with open(dir+'filesiwanttofind.txt', "r") as wanted:
wantedfiles = []
for line in wanted:
    wantedfiles.extend(line.split())

with open(dir+'newS34catalog.txt', "r") as newcatalog:
    for line in newcatalog:
        if any(wanted in line.split() for wanted in wantedfiles):
            print(line.rstrip())

答案 5 :(得分:0)

如果您追求速度和轻便程度,请设置成员资格检查并通过单个生成器管道运行整个搜索将为您带来最佳效果。下面的代码本可以进一步优化,但这似乎是可读性和高性能之间的中间点。希望能帮助到你。如果您还没有,请看看beazely风格的python生成器,它们很棒,并且公然为您的代码增加了速度。

# create a set of targets to quickly look up targets
targets = {i.strip() for i in open('targets.txt','r') if i.strip()}

# clean trailing whitespace on each line
results = (i.strip() for i in open('haystack.txt','r'))
# only process lines with a space
results = (i for i in results if ' ' in i)
# filter lines that have words that intersect with targets
results = (i for i in results if targets.intersection(i.split(' ')[:2]))

# display the results
for line in results:
    print(line)