Используя ОС.scandir получить все txt файлы в подпапках


У меня есть родитель реж, что х детей Дирс друг с Y txt файлы. Я хочу перечислить все txt файлы. Есть ли способ упростить это?

for entry in os.scandir(DIR): 
        for subentry in os.scandir(entry.path):
            if subentry.is_dir():
                for file in os.scandir(subentry.path):
                    if file.is_file() and file.name.endswith("txt"):
                        print(file.name)


3284
0
задан 3 февраля 2018 в 08:02 Источник Поделиться
Комментарии
1 ответ

Есть (как минимум) два способа добиться этого легко. Первое это то, что @Ludisposed предложено в комментариях, glob. Он может также рекурсивно в подкаталогах с ** (в Python 3):

import glob

def get_txt_files(base_dir):
return glob.iglob(f"{base_dir}/**/*.txt", recursive=True)

Или, если вы используете Windows, которая использует различные разделители для пути:

def get_txt_files(base_dir):
return glob.iglob(rf"{base_dir}\**\*.txt", recursive=True)

Другой является в основном то, что @маст предложил, также в комментариях, сделать это полностью рекурсивной функции:

def get_txt_files(base_dir):
for entry in os.scandir(base_dir):
if entry.is_file() and entry.name.endswith(".txt"):
yield entry.name
elif entry.is_dir():
yield from get_txt_files(entry.path)
else:
print(f"Neither a file, nor a dir: {entry.path}")

Обе функции возвращают итераторы. Вы можете напечатать все имена с простым for петли:

for name in get_txt_files("foo"):
print(name)

Если ваш каталог X также содержит txt файлы, то они будут получены из этих функций. Вы можете избежать этого с glob сделав глубокий уровень явные:

def get_txt_files(base_dir):
return glob.iglob(f"{base_dir}/*/*.txt")

В-третьих, очень похожие, способ заключается в использовании pathlib.Path (в Python 3), который также имеет glob способ (что напрямую возвращает итератор). Таким образом, вы можете быть уверены, что это работает как на Unix, так и Windows:

from pathlib import Path

def get_txt_files(base_dir):
return Path(base_dir).glob("*/*.txt")

5
ответ дан 3 февраля 2018 в 09:02 Источник Поделиться