回答:
Python 3.5以降では、新しい再帰**/
機能を使用します。
configfiles = glob.glob('C:/Users/sam/Desktop/file1/**/*.txt', recursive=True)
recursive
が設定されている場合**
、パス区切り文字が後に続き、0個以上のサブディレクトリに一致します。
以前のバージョンのPythonでは、glob.glob()
サブディレクトリ内のファイルを再帰的にリストできません。
その場合os.walk()
、fnmatch.filter()
代わりにと組み合わせて使用します:
import os
import fnmatch
path = 'C:/Users/sam/Desktop/file1'
configfiles = [os.path.join(dirpath, f)
for dirpath, dirnames, files in os.walk(path)
for f in fnmatch.filter(files, '*.txt')]
これはディレクトリを再帰的にたどり、すべての絶対パス名を一致する.txt
ファイルに返します。この特定のケースでfnmatch.filter()
は、やり過ぎかもしれませんが、.endswith()
テストを使用することもできます。
import os
path = 'C:/Users/sam/Desktop/file1'
configfiles = [os.path.join(dirpath, f)
for dirpath, dirnames, files in os.walk(path)
for f in files if f.endswith('.txt')]
path to directory
。
recursive=False
して**/
いるわけではありませんが、機能と一緒に設定すると、特定のフォルダーだけでなく、その子にあるファイルのリストが提供されないのはなぜですか?
**/
のディレクトリ名のリストが表示さ/
れrecursive=False
ます。基本的に*
、と同じように一致するdoubleがあり、*/
効率が低下します。
*/*
すべてのサブディレクトリにあるすべてのファイルが必要な場合に使用します。
直下のサブディレクトリでファイルを検索するには:
configfiles = glob.glob(r'C:\Users\sam\Desktop\*\*.txt')
すべてのサブディレクトリを走査する再帰バージョンでは、Python 3.5以降を使用**
して渡すことができます。recursive=True
configfiles = glob.glob(r'C:\Users\sam\Desktop\**\*.txt', recursive=True)
どちらの関数呼び出しもリストを返します。glob.iglob()
パスを1つずつ返すために使用できます。または使用pathlib
:
from pathlib import Path
path = Path(r'C:\Users\sam\Desktop')
txt_files_only_subdirs = path.glob('*/*.txt')
txt_files_all_recursively = path.rglob('*.txt') # including the current dir
どちらのメソッドもイテレータを返します(パスは1つずつ取得できます)。
glob()
、ディレクトリのパターンをサポートすることも期待していませんでした。
**
再帰ケースのドキュメントの更新が含まれています。ただし、**
機能させるには、スイッチを設定する必要がありますrecursion=True
。
このトピックについては多くの混乱があります。私がそれを明確にできるかどうか見てみましょう(Python 3.7):
glob.glob('*.txt') :
現在のディレクトリの「.txt」で終わるすべてのファイルに一致しますglob.glob('*/*.txt') :
1と同じglob.glob('**/*.txt') :
「.txt」で終わるすべてのファイルを、直接のサブディレクトリのみに一致させます現在のディレクトリでは、glob.glob('*.txt',recursive=True) :
1と同じglob.glob('*/*.txt',recursive=True) :
3と同じglob.glob('**/*.txt',recursive=True):
現在のディレクトリとすべてのサブディレクトリの「.txt」で終わるすべてのファイルに一致しますしたがって、常に指定することをお勧めします recursive=True.
glob2のパッケージには、ワイルドカードをサポートし、適度に高速であります
code = '''
import glob2
glob2.glob("files/*/**")
'''
timeit.timeit(code, number=1)
私のラップトップでは、60,000を超えるファイルパスに一致するのに約2秒かかります。
Python 2.6でFormicを使用できます
import formic
fileset = formic.FileSet(include="**/*.txt", directory="C:/Users/sam/Desktop/")
開示-私はこのパッケージの作成者です。
以下は、glob.glob
を使用せずに同様の機能を可能にする適応バージョンですglob2
。
def find_files(directory, pattern='*'):
if not os.path.exists(directory):
raise ValueError("Directory not found {}".format(directory))
matches = []
for root, dirnames, filenames in os.walk(directory):
for filename in filenames:
full_path = os.path.join(root, filename)
if fnmatch.filter([full_path], pattern):
matches.append(os.path.join(root, filename))
return matches
したがって、次のdir構造がある場合
tests/files
├── a0
│ ├── a0.txt
│ ├── a0.yaml
│ └── b0
│ ├── b0.yaml
│ └── b00.yaml
└── a1
あなたはこのようなことをすることができます
files = utils.find_files('tests/files','**/b0/b*.yaml')
> ['tests/files/a0/b0/b0.yaml', 'tests/files/a0/b0/b00.yaml']
fnmatch
ファイル名だけではなく、ファイル名全体でほとんどのパターンが一致します。
configfiles = glob.glob('C:/Users/sam/Desktop/**/*.txt")
すべてのケースで機能するわけではなく、代わりにglob2を使用します
configfiles = glob2.glob('C:/Users/sam/Desktop/**/*.txt")
Python 3.4以降を実行している場合は、pathlib
モジュールを使用できます。このPath.glob()
メソッド**
は「このディレクトリとすべてのサブディレクトリを再帰的に」というパターンをサポートしています。Path
一致するすべてのファイルのオブジェクトを生成するジェネレータを返します。
from pathlib import Path
configfiles = Path("C:/Users/sam/Desktop/file1/").glob("**/*.txt")
Martijnが指摘したように、globは**
Python 3.5で導入された演算子を介してのみこれを行うことができます。OPがglobモジュールを明示的に要求したため、以下は同様に動作する遅延評価反復子を返します
import os, glob, itertools
configfiles = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.txt'))
for root, dirs, files in os.walk('C:/Users/sam/Desktop/file1/'))
ただしconfigfiles
、このアプローチでは1回しか反復できないことに注意してください。複数の操作で使用できる構成ファイルの実際のリストが必要な場合は、を使用して明示的に作成する必要がありますlist(configfiles)
。
このコマンドrglob
は、ディレクトリ構造の最も深いサブレベルまで無限に再帰します。ただし、深さを1レベルだけにする場合は、使用しないでください。
OPがglob.globの使用について話していることを理解しています。これは、すべてのサブフォルダーを再帰的に検索するという意図に応えると思います。
このrglob
関数は最近、フォルダー構造をデータの読み取り順序の固定仮定として使用していたデータ処理アルゴリズムの速度を100倍向上させました。ただし、rglob
指定した親ディレクトリ以下のすべてのファイルを1回スキャンして、ファイル名をリスト(100万個を超えるファイル)に保存し、そのリストを使用して、どのファイルを開く必要があるかを判断できました。ファイルの命名規則のみに基づいて、またはそれらがどのフォルダーにあったかに基づいて、将来的にポイントします。