1

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

它的目标是能够按内容搜索文件。(我们主要谈论的是源文件、文本文件,而不是图像/二进制文件——即使在他们的元数据中搜索会是一个很大的改进)。现在我不使用正则表达式,随意的纯文本。

这部分算法效果很好!

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

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

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

编辑:要清楚,我想搜索文件内容的一部分。因此,对其所有内容进行 md5 散列并将其与我正在搜索的散列进行比较并不是一个好主意;)

4

4 回答 4

4

这里我使用 whoosh lib 进行搜索/索引.. 上部分是索引文件,下部分是演示搜索..

#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']
于 2012-11-21T17:10:50.767 回答
1

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

因此,您可以创建一个 [file_id, filename] 表和一个 [file_id, line_number, line_text] 表,并使用它们作为查询的基础。即:有多少文件包含这个词和那一行,哪些行包含这个和这个但不包含等等......

于 2012-11-21T16:56:03.027 回答
1

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

例如,Apple 能够在发送或接收文本的任何时候识别 iPhone 的 GPS 位置。但是,他们不能合法地做的是将该位置数据与任何可能与您作为个人相关联的东西相关联。

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

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

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

于 2016-02-08T18:37:26.530 回答
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
于 2012-11-21T16:38:35.533 回答