148

フォルダー内の一連のサブフォルダーを開き、いくつかのテキスト ファイルを見つけて、テキスト ファイルのいくつかの行を印刷したいと考えています。私はこれを使用しています:

configfiles = glob.glob('C:/Users/sam/Desktop/file1/*.txt')

ただし、これはサブフォルダーにもアクセスできません。同じコマンドを使用してサブフォルダーにもアクセスする方法を知っている人はいますか?

4

13 に答える 13

219

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')]
于 2013-02-10T13:31:59.937 に答える
25

直下のサブディレクトリでファイルを検索するには:

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 つずつ取得できます)。

于 2013-02-10T13:47:12.467 に答える
17

glob2パッケージはワイルドカードをサポートし、かなり高速です

code = '''
import glob2
glob2.glob("files/*/**")
'''
timeit.timeit(code, number=1)

私のラップトップでは、 60,000 を超えるファイル パスを照合するのに約 2 秒かかります。

于 2014-03-13T19:10:15.290 に答える
9

Formicは Python 2.6 で使用できます

import formic
fileset = formic.FileSet(include="**/*.txt", directory="C:/Users/sam/Desktop/")

開示 - 私はこのパッケージの作者です。

于 2013-02-12T01:12:09.837 に答える
4

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

したがって、次のディレクトリ構造がある場合

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ファイル名のみではなく、ファイル名全体でかなりのパターン一致。

于 2015-03-26T02:20:41.323 に答える
2

glob2 パッケージをインストールできれば...

import glob2
filenames = glob2.glob("C:\\top_directory\\**\\*.ext")  # Where ext is a specific file extension
folders = glob2.glob("C:\\top_directory\\**\\")

すべてのファイル名とフォルダー:

all_ff = glob2.glob("C:\\top_directory\\**\\**")  
于 2016-07-26T15:05:32.993 に答える
0

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)

于 2015-12-05T23:45:30.280 に答える