创建文件夹中每个文件内容的索引

时间:2012-11-21 16:25:06

标签: python search

我正在使用Python制作搜索工具。

其目标是能够按内容搜索文件。 (我们主要谈的是源文件,文本文件,而不是图像/二进制文件 - 即使在他们的METADATA中搜索也是一个很好的改进)。现在我不使用正则表达式,简单的普通文本。

这部分算法效果很好!

问题在于我意识到我主要在相同的几个文件夹中搜索,我想找到一种方法来构建文件夹中每个文件内容的索引。并且能够尽快知道我正在搜索的句子是否在xxx.txt中,或者它是否在那里。 现在的想法是为每个文件维护一个校验和,使我能够知道它是否包含特定的字符串。

你知道任何算法接近这个吗?

我不需要100%的成功率,我更喜欢一个小指数,而不是一个100%成功的大指数。 我们的想法是提供一个通用工具。

编辑:要清楚,我想搜索该文件内容的一部分。所以制作一个md5哈希的所有内容&将它与我正在搜索的哈希进行比较并不是一个好主意;)

4 个答案:

答案 0 :(得分:3)

这里我使用whoosh lib进行搜索/索引.. .upper部分索引文件,下半部分是demo搜索..。

#indexing part

from whoosh.index import create_in
from whoosh.fields import *
import os
import stat
import time

schema = Schema(FileName=TEXT(stored=True), FilePath=TEXT(stored=True), Size=TEXT(stored=True), LastModified=TEXT(stored=True),
                LastAccessed=TEXT(stored=True), CreationTime=TEXT(stored=True), Mode=TEXT(stored=True))

ix = create_in("./my_whoosh_index_dir", schema)
writer = ix.writer()



for top, dirs, files in os.walk('./my_test_dir'):
    for nm in files:
        fileStats = os.stat(os.path.join(top, nm))
        fileInfo = {
            'FileName':nm,
            'FilePath':os.path.join(top, nm),
            'Size' : fileStats [ stat.ST_SIZE ],
            'LastModified' : time.ctime ( fileStats [ stat.ST_MTIME ] ),
            'LastAccessed' : time.ctime ( fileStats [ stat.ST_ATIME ] ),
            'CreationTime' : time.ctime ( fileStats [ stat.ST_CTIME ] ),
            'Mode' : fileStats [ stat.ST_MODE ]
        }
        writer.add_document(FileName=u'%s'%fileInfo['FileName'],FilePath=u'%s'%fileInfo['FilePath'],Size=u'%s'%fileInfo['Size'],LastModified=u'%s'%fileInfo['LastModified'],LastAccessed=u'%s'%fileInfo['LastAccessed'],CreationTime=u'%s'%fileInfo['CreationTime'],Mode=u'%s'%fileInfo['Mode'])

writer.commit()


## now the seaching part
from whoosh.qparser import QueryParser
with ix.searcher() as searcher:
    query = QueryParser("FileName", ix.schema).parse(u"hsbc") ## here 'hsbc' is the search term
    results = searcher.search(query)
    for x in results:
        print x['FileName']

答案 1 :(得分:1)

这不是最有效的,但只使用stdlib和一点点工作。 sqlite3(如果在编译时启用)支持全文索引。请参阅:http://www.sqlite.org/fts3.html

因此,您可以创建一个[file_id,filename]表和一个[file_id,line_number,line_text]表,并使用这些表来查询。即:有多少文件包含这个单词和那一行,哪些行包含这个AND这个但不是等...

答案 2 :(得分:1)

任何人想要一个能够搜索文件“某些部分”的工具的唯一原因是他们试图做的是分析对你可以阅读哪些部分有法律限制的数据。

例如,Apple可以在发送或接收文本的任何时刻识别iPhone的GPS位置。但是,他们不能合法地做的是将位置数据与任何可能与您个人联系在一起的东西联系起来。

在广泛的范围内,您可以使用这样的模糊数据来跟踪和分析大量数据中的模式。您可以为美国的每部手机分配一个唯一的“虚拟ID”并记录所有位置移动;之后,您实施了一种检测旅行模式的方法。可以通过其正常行进模式的偏差来检测异常值。然后,“metadeta”可以与来自外部来源的数据相结合,例如零售地点的名称和位置。考虑一下您可以通过算法检测的所有情况。就像足球老爸一样,3年来他一直在工作,家庭,餐馆和小联盟领域之间走同一条路。只有能够搜索文件的一部分仍然提供足够的数据来检测足球爸爸的电话的独特签名突然偏离正常程序并进入枪支店。可能性是无限的。这些数据可以与当地执法部门共享,以增加附近公共场所的街道存在;同时保持手机所有者的匿名性。

如果没有IggY正在寻找的方法,在今天的环境中,上述示例的功能在法律上是不可能的。

另一方面,他可能只是在某些文件类型中寻找某些类型的数据。如果他知道文件中的哪个位置需要搜索他需要的数据,他可以节省主CPU时间,只读取文件的后半部分或上半部分。

答案 3 :(得分:0)

您可以执行如下的简单基于名称的缓存。如果文件内容不会发生变化,这可能是最好的(最快的)。否则,您可以MD5文件内容。我说MD5因为它比SHA快,而且这个应用程序似乎对安全性不敏感。

from hashlib import md5
import os

info_cache = {}

for file in files_to_search:
    file_info = get_file_info(file)
    file_hash = md5(os.path.abspath(file)).hexdigest()
    info_cache[file_hash]=file_info