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

ファイルの「特定の部分」を検索できるツールが必要な唯一の理由は、彼らがしようとしているのは、読み取り可能な部分に法的制限があるデータを分析することだからです。

たとえば、Apple には、テキストが送受信された瞬間に iPhone の GPS 位置を特定する機能があります。しかし、彼らが法的にできないことは、その位置データを個人として関連付けることができるものと関連付けることです.

このようなあいまいなデータを使用して、大量のデータ全体のパターンを追跡および分析できます。米国内のすべての携帯電話に一意の「仮想 ID」を適切に割り当て、すべての場所の移動を記録できます。その後、移動パターンを検出する方法を実装します。外れ値は、通常の移動パターンの偏差によって検出できます。その「メタデータ」は、小売店の名前や場所などの外部ソースからのデータと組み合わせることができます。アルゴリズムで検出できる可能性のあるすべての状況を考えてみてください。3 年間、職場、自宅、レストラン、リトル リーグ競技場の間の一般的なルートを同じように運転してきたサッカーのお父さんのように。ファイルの一部しか検索できない場合でも、サッカー パパの電話を検出するのに十分なデータが得られます。」独特のシグニチャーが突如日常を離れ、ガンショップに足を踏み入れた。可能性は無限です。そのデータを地元の法執行機関と共有して、近くの公共スペースでの道路の存在感を高めることができます。電話の所有者の匿名性を維持しながら。

上記の例のような機能は、IggY が探している方法がなければ、今日の環境では法的に不可能です。

一方、特定のファイル タイプの特定のタイプのデータのみを探している可能性もあります。必要なデータを検索したいファイル内の場所がわかっている場合は、ファイルの後半または前半のみを読み取るだけで、主要な CPU 時間を節約できます。

于 2016-02-08T18:37:26.530 に答える
1

これは最も効率的ではありませんが、stdlib と少しの作業を使用するだけです。sqlite3 (コンパイル時に有効になっている場合) は全文索引付けをサポートします。参照: http://www.sqlite.org/fts3.html

したがって、[file_id, filename] のテーブルと [file_id, line_number, line_text] のテーブルを作成し、それらを使用してクエリのベースにすることができます。つまり、この単語とその行を含むファイルの数、これとこれを含むが含まない行など...

于 2012-11-21T16:56:03.027 に答える
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 に答える