Pythonを使用した高速ファイル検索(ファイル検索インデックスを作成)

基本的な検索方法:

pathlibライブラリを使用したファイルの検索Pythonを使用してファイルを検索する場合は、pathlibライブラリのglob()関数とrglob()関数を使用する必要があります。glob()関数は、ファイル名ベースの検索メソッドを実装できます。 rglob関数は、拡張機能ベースの検索方法を実装できます。


from pathlib import Path

base_dir = '/Users/edz/Desktop/'
keywords = '**/*BBC*'

# 遍历base_dir指向的目录下所有的文件
p = Path(base_dir)

# 当前目录下包含BBC的所有文件名称
files = p.glob(keywords)  
# files的类型是迭代器
# 通过list()函数转换为列表输出
# print(list(files))

# xlsx结尾的文件
files2 = p.rglob('*.xlsx')
print(list(files2))

# 遍历子目录和所有文件
files3 = p.glob('**/*')
print(list(files3))

glob()は、「c:\ somepath \ to \ filename_include_BBC_voice.exe」などのファイルのパスとファイル名と一致するため、通常、「BBC」などのファイルを検索するときにキーワードを使用します。 「BBC」などのワイルドカードフォームをキーワードに追加する必要があります。

ワイルドカードは、正規表現のメタ文字に似た特殊な記号です。正規表現では使用できませんが、glob(フルネームグローバル)マッチングパターンでのみ使用できます。
ここに画像の説明を挿入
rglob関数は、ファイルパスの末尾から前方にマッチングを実行します。これは、この関数とglob()関数の主な違いです。rglob()関数の検索順序の特性に基づいて、拡張子の検索によく使用されます。たとえば、rglob('* .xlsx')を使用してxlsx拡張子を持つすべてのファイルを検索します。これは、glob()を使用して記述されたパターンマッチングよりも単純であり、引数の意味がより明確になります。

最後に、glob()関数とrglob()関数の戻り値を見ると、それらの実行の結果は、前のレッスンで触れていない新しいデータ型であることに注意する必要があります。この型は「イテレータ""。

検索効率を向上させる2つの方法

Pythonのpathlibライブラリを使用してファイル検索を実装すると、Windowsのデフォルトの検索よりも柔軟性が高くなりますが、検索効率は向上しません。次に、検索の待ち時間を短縮するために、検索パスを指定する方法と、pathlibライブラリの検索効率を向上させるためのインデックスファイルを作成する方法の2つを使用する方法を説明します。

検索パスを指定する

検索パスを指定して、最初のものを見てみましょう。
これは3つのステップで行う必要があります。

最初に構成ファイルを生成し、検索するパスを構成ファイルに書き込みます。

次に、カスタム関数を記述して、構成ファイルを読み取って検索し、構成ファイル内のパスを読み取り、ディレクトリごとに検索します。

最後に、複数のディレクトリの検索結果が組み合わされて出力されるため、結果から目的のファイルをすばやく見つけることができます。

最初のステップである、Pythonを使用して構成ファイルを読み取る方法について説明しましょう。以前は、検索するパスを変数に記述し、パスを定義する変数名をコードの最初の数行に配置して、次回検索ディレクトリが変更されたときに変数を見つけられるようにしました。ただし、コードエンジニアリングが少し複雑なプログラムの場合、複数のコードファイルが存在することが多く、検索を実行するたびに検索パスを変更することはできません。新しいアプローチは、変数をコードの構成ファイルと呼ばれる別のファイルに入れることです。

このアプローチの利点は、検索ディレクトリを変更するときにコードファイルを開く必要がないことです。友人にも同様の関数が必要だとすると、Pythonをまったく知らなくても、コードと構成ファイルを一緒に送信できます。彼は、作成したプログラムを使用して効率的な検索を実行できます。

構成ファイルは通常、テキストファイルです。構成ファイルの形式は、通常、ソフトウェアの機能とその習慣に基づいてソフトウェアの作成者が指定しますが、一般的な構成ファイルの形式もあります。

たとえば、Windowsシステムでは、最も一般的な構成ファイルは拡張子が.iniのファイルです。今日のレッスンでは、構成ファイルの標準形式として.iniファイル形式を使用します。.iniファイル形式は、3つのセクション、セクション、パラメーター、およびコメントで構成されています。形式は次のとおりです。

[section]
参数
(键=值)
  name=value
注释 
注释使用“;”分号表示。在分号后面的文字,直到该行结尾都全部为注解。
;注释内容
#基于.ini 文件的格式,我把配置搜索路径的配置文件修改为如下:
[work]
;工作文件保存路径
searchpath=/Users/edz,/tmp

[game]
;娱乐文件保存路径
searchpath=/games,/movies,/music

このコードでは、仕事と遊びをそれぞれ表す2つの「セクション」を仕事とゲーム用に設定しました。この設定の利点は、さまざまな目的でさまざまなディレクトリを検索できることです。検索に使用するディレクトリが少ない場合は、それに応じて検索の待機時間が短縮されます。

さらに、2つの「セクション」のパラメーターが同じ名前--searchpathとして指定されていることがわかります。この設定の利点は、検索範囲を「仕事」から「娯楽」に変更したときに、必要なのはコード内で変更するには検索パラメータを変更せずに、検索の「セクション」。

「section」と「parameter」に加えて、構成ファイルでは、パラメーターsearchpathの値を設定する方法にも注意を払う必要があります。その値は、より便利にするために、検索するパス範囲です。プログラムの複数のパスを読み取るには、コンマを使用して複数のパスを区切ります。

search.iniファイルのフルパスを見つけたら、.iniファイル形式を読み取って分析する必要があります。Pythonには、この関数を実装するconfigparserライブラリと呼ばれるライブラリがあります。このライブラリを使用すると、検索パスを直接読み取ることができます。 .iniファイルのパラメータ。read()関数を使用してファイルの内容を読み取り、.iniファイルを分析するためのスクリプトを手動で作成する必要はありません。


import configparser
import pathlib 
from pathlib import Path

def read_dirs(ini_filename, section, arg):
    """
    通过ini文件名,节和参数取得要操作的多个目录
    """
    current_path = pathlib.PurePath(__file__).parent
    inifile = current_path.joinpath(ini_filename)

    # cf是类ConfigParser的实例
    cf = configparser.ConfigParser()

    # 读取.ini文件
    cf.read(inifile)

    # 读取work节 和 searchpath参数 
    return cf.get(section, arg).split(",")

def locate_file(base_dir, keywords):
    p = Path(base_dir)
    files = p.glob(keywords) 
    return list(files)


dirs = read_dirs('search.ini', 'work', 'searchpath')
# ['/Users/edz', '/tmp']
keywords = '**/*BBC*'

# 定义存放查找结果的列表
result = []

# 从每个文件夹中搜索文件
for dir in dirs:
    files = locate_file(dir, keywords)
    result += files

# 将PosixPath转为字符串
print( [str(r) for r in result] )

read_dirs()関数は、.iniファイルの読み取りを実装し、リスト型として返された複数のパスを処理します。リストタイプは、複数のサイドバイサイドデータセットに適しており、複数のディレクトリは、リストデータタイプを使用して、検索するディレクトリの名前を格納できます。

Locate_file()関数は、コードの35行目のループ関数を介して各ディレクトリを検索し、検索結果を結果変数に格納します。結果変数はリストデータ型です。検索されたファイルには一致する複数のファイルパスが含まれている可能性があるため、検索結果を結果リストに順番に保存してから、次のディレクトリの検索を続行し、append( )function to結果がリストに入れられ、すべてのディレクトリ検索が完了するまで、検索プログラム全体が実際に実行されることはありません。

最後に、パス処理の過程で、異なるオペレーティングシステムのパス書き込み方法の違いを回避するために、pathlibライブラリがパスをPosixPath()オブジェクトとして一律に定義するという事実に注意する必要があります。したがって、これらのパスを使用する場合は、最初にPosixPathオブジェクトを文字列タイプに変換する必要があります。コードの最後の行では、Pythonの組み込み関数str()関数を使用して、PosixPathオブジェクトを1つずつ文字列型に変換し、それらをリストに再度格納します。

インデックスファイル

検索パスを指定するプログラムに基づいて変更を加えることができます。まず、構成ファイルディレクトリ内のすべてのファイルパスの保存方法をリストからファイルに変更し、次に検索機能を変更してファイルから検索します。


def locate_file(base_dir, keywords='**/*'):
    """
    迭代目录下所有文件
    """
    p = Path(base_dir)
    return p.glob(keywords)

def write_to_db():
    """
    写入索引文件
    """
    current_path = pathlib.PurePath(__file__).parent
    dbfile = current_path.joinpath("search.db")

    with open(dbfile, 'w', encoding='utf-8') as f:
        for r in result:
            f.write(f"{
      
      str(r)}\n")

# 读取配置文件
dirs = read_dirs('search.ini', 'work', 'searchpath')

# 遍历目录
result = []
for dir in dirs:
    for files in locate_file(dir):
        result.append(files)

# 将目录写入索引文件
write_to_db()

コードでは、コードの16〜18行目にあるwrite_to_db()関数を追加し、リストへの書き込み関数をファイルへの書き込みに置き換えました。同時に、すべてのディレクトリをトラバースするために、locate_file()関数の2番目のパラメーターも変更し、に変更しました“keywords='/*'”これらの2つの変更により、すべてのファイルパスがsearch.dbファイルに保存されます。****

search.dbファイルの内容は次のとおりです。これは、構成ファイルで指定されたすべてのディレクトリのすべてのファイルパスを記録します。


/tmp/com.apple.launchd.kZENgZTtVz
/tmp/com.google.Keystone
/tmp/mysql.sock
/tmp/com.adobe.AdobeIPCBroker.ctrl-edz
/tmp/com.apple.launchd.kZENgZTtVz/Listeners
/tmp/com.google.Keystone/.keystone_install_lock
... ...

テキストからキーワードを検索する


import pathlib 
import re

keyword = "apple"

# 获取索引文件路径
current_path = pathlib.PurePath(__file__).parent
dbfile = current_path.joinpath("search.db")

# 在索引文件中搜索关键字
with open(dbfile, encoding='utf-8') as f:
    for line in f.readlines():
        if re.search(keyword, line):
            print(line.rstrip())

コードでは、正規表現のre.search()検索関数を使用し、検索キーワードとしてキーワード変数を使用して、search.dbインデックスファイルの各行を照合し、最後にキーワード「apple」のファイルパスを照合します。 「名前とともに画面に表示されます。

この方法でファイルを検索するのは、オペレーティングシステム独自の検索ツールを使用するよりもはるかに高速です。これは、Windowsがハードドライブ上のファイルを検索するのにかかる時間を2つの部分に分割したためです。その一部はupdatedb.pyがインデックスを作成するときであり、一部はsearch.dbインデックスファイルからキーワードを探すときです。

おすすめ

転載: blog.csdn.net/david2000999/article/details/121555024