1

我正在尝试获取所有文本和 Python 文件的过滤列表,如下所示

from walkdir import filtered_walk, dir_paths, all_paths, file_paths
vdir=raw_input ("enter director :")

files = file_paths(filtered_walk(vdir, depth=0,included_files=['*.py', '*.txt']))

我想要:

  1. 知道在给定目录中找到的文件总数

    我尝试过类似的选项: Number_of_files= len (files) 或 for n in files n=n+1 但所有都失败了,因为“文件”是我在 python 文档上搜索但无法使用的称为“生成器”的对象它

  2. 我还想在上面找到的文件列表中找到一个字符串,例如“import sys”,并将具有我的搜索字符串的文件名存储在名为“found.txt”的新文件中

4

4 回答 4

1

我相信这可以满足您的要求,如果我误解了您的规格,请在您进行测试后告诉我。我已经对目录进行了硬编码searchdir,因此您必须提示输入它。

import os

searchdir = r'C:\blabla'
searchstring = 'import sys'

def found_in_file(fname, searchstring):
    with open(fname) as infp:
        for line in infp:
            if searchstring in line:
                return True
        return False

with open('found.txt', 'w') as outfp:
    count = 0
    search_count = 0
    for root, dirs, files in os.walk(searchdir):
        for name in files:
            (base, ext) = os.path.splitext(name)
            if ext in ('.txt', '.py'):
                count += 1

            full_name = os.path.join(root, name)
            if found_in_file(full_name, searchstring):
               outfp.write(full_name + '\n')
               search_count += 1

print 'total number of files found %d' % count
print 'number of files with search string %d' % search_count

使用with打开文件也将在以后自动为您关闭文件。

于 2012-05-18T12:24:35.387 回答
0

python 生成器是一种特殊的迭代器。它一个接一个地产生一个项目,而不事先知道有多少项目。你只能在最后才知道。

不过,应该没问题

n = 0
for item in files:
    n += 1
    do_something_with(items)
print "I had", n, "items."
于 2012-05-18T10:24:03.613 回答
0

您可以将生成器(或通常称为迭代器)视为一次提供一个项目的列表。(不,它不是一个列表)。因此,除非您将它们全部看完,否则您无法计算它会给您多少物品,因为您必须一件一件地拿走它们。(这只是一个基本的想法,现在你应该能够理解文档了,我相信这里也有很多关于它们的问题)。

现在,对于您的情况,您使用了一种不太错误的方法:

count = 0
for filename in files:
    count += 1

你做错了什么是采取f和增加,但f这里是文件名!递增是没有意义的,也是一个异常。

一旦你有了这些文件名,你必须打开每个单独的文件,阅读它,搜索你的字符串并返回文件名。

def contains(filename, match):
    with open(filename, 'r') as f:
        for line in f:
            if f.find(match) != -1:
                return True
    return False

match_files = [] for filename in files: if contains(filename, "import sys"): match_file.append(filename) # or a one-liner: match_files = [f for f in files if contains(f, "import sys" )]

现在,作为生成器的示例(在阅读文档之前不要阅读此内容):

def matching(filenames):
    for filename in files:
        if contains(filename, "import sys"):
            # feed the names one by one, you are not storing them in a list
            yield filename
# usage:
for f in matching(files):
    do_something_with_the_files_that_match_without_storing_them_all_in_a_list()
于 2012-05-18T10:28:24.233 回答
-1

你应该试试 os.walk

import os
dir = raw_input("Enter Dir:")
files = [file for path, dirname, filenames in os.walk(dir) for file in filenames if file[-3:] in [".py", ".txt"]]

nfiles = len(files)
print nfiles

要在文件中搜索字符串,请查看在 txt 文件 Python中搜索字符串

将这两者结合起来,您的代码将类似于

import os
import mmap

dir = raw_input("Enter Dir:")
print "Directory %s" %(dir) 
search_str = "import sys" 
count = 0
search_count = 0
write_file = open("found.txt", "w")
for dirpath, dirnames, filenames in os.walk(dir):
    for file in filenames:
        if file.split(".")[-1] in ["py", "txt"]:
            count += 1
            print dirpath, file
            f = open(dirpath+"/"+file)
            #            print f.read()

            if search_str in f.read():
                search_count += 1
                write_file.write(dirpath+"/"+file)

write_file.close()
print "Number of files: %s" %(count)
print "Number of files containing string: %s" %(search_count)
于 2012-05-18T10:24:00.823 回答