Как на Python найти файлы, имеющие определенное расширение

Чтобы при помощи кода на Python найти все файлы, имеющие заданное расширение, можно использовать функцию os.walk. С ее помощью вы обойдете структуру каталогов и проверите расширение каждого файла, используя метод file.endswith().

Скачивайте книги ТОЛЬКО на русском языке у нас в телеграм канале: PythonBooksRU

Примечание редакции: о том, как вообще выводить списки файлов , читайте в статье “Как получить список файлов в каталоге с помощью Python”.

Например, давайте найдем все файлы с расширением .txt:

import os

for root, dirs, files in os.walk('/path/to/directory'):
    for file in files:
        if file.endswith('.txt'):
            print(os.path.join(root, file))

Этот код выведет полный путь ко всем файлам с расширением .txt в указанном каталоге. Вы можете заменить .txt на любое другое расширение файла.

Если вы ищете быстрый ответ, я уверен, что вышеприведенное решение подойдет!

Но если вы хотите улучшить свои навыки работы с Python и узнать, как рекурсивно находить файлы в каталоге с подкаталогами, продолжайте читать. Это руководство познакомит вас с тремя методами, которые можно использовать для поиска файлов определенного типа в Python.

Давайте приступим!

Поиск файлов по расширению в Python

Python предлагает три основных способа поиска файлов по расширению:

  1. Модуль glob
  2. Функция os.listdir
  3. Функция os.walk

Давайте рассмотрим подробнее, как работает каждый из этих подходов.

1. Модуль glob

Для примера найдем при помощи модуля Python glob все файлы, имеющие расширение .txt:

import glob

# Find all files with the .txt extension in the current directory
txt_files = glob.glob('*.txt')

# Print the names of the files found
print(txt_files)

Функция glob.glob() ищет в текущем каталоге все файлы, соответствующие заданному шаблону. В данном случае шаблон – '*.txt', т.е. все файлы, имена которых заканчиваются на .txt. Результатом будет список имен файлов.

Вы также можете указать другой каталог для поиска, передав путь к каталогу в качестве первого аргумента функции glob.glob(). Например, если вы хотите найти все файлы .txt в каталоге /path/to/directory, выполните следующее:

import glob

# Find all files with the .txt extension in the specified directory
txt_files = glob.glob('/path/to/directory/*.txt')

# Print the names of the files found
print(txt_files)

Пример

У меня есть проект со следующей древовидной структурой:

.
├── Data
│   ├── ages.txt
│   └── numbers.txt
├── Images
│   └── image.png
├── Samples
│   ├── codes.txt
│   └── readme.txt
├── finder.py
├── names.txt
└── values.txt

Давайте при помощи Python найдем в текущей папке все текстовые файлы, т.е. имеющие расширение .txt. Для этого выполним код из предыдущего раздела и посмотрим, что произойдет:

import glob

# Find all files with the .txt extension in the current directory
txt_files = glob.glob('*.txt')

# Print the names of the files found
print(txt_files)

# Вывод:
# ['names.txt', 'values.txt']

Код возвращает файлы 'names.txt' и 'values.txt', но не текстовые файлы во вложенных папках. Чтобы перечислить файлы с определенным расширением во вложенных папках, необходимо использовать рекурсивный подход.

2. Рекурсивный поиск файлов с определенным расширением

Как вы видели в предыдущем примере, функция glob.glob() ищет файлы только в указанном каталоге и не ищет ни в одном из его подкаталогов.

Для поиска файлов с определенным расширением в указанном каталоге и во всех его подкаталогах можно использовать функцию os.listdir() рекурсивным способом.

Вот пример реализации:

import os

def find_files(dir_path, extension):
    # Check if the given path is a valid directory
    if not os.path.isdir(dir_path):
        return

    # Get a list of all the files and directories in the given directory
    files_and_dirs = os.listdir(dir_path)

    # Iterate over the list of files and directories
    for file_or_dir in files_and_dirs:
        # Construct the full path of the file or directory
        full_path = os.path.join(dir_path, file_or_dir)
    
        # If the full path is a directory, recursively call the function to find the files in that directory
        if os.path.isdir(full_path):
            find_files(full_path, extension)
        else:
            # If the full path is a file that ends with extension, print its path
            if full_path.endswith(extension):
                print(full_path)

Этот код определяет рекурсивную функцию find_files(), которая принимает в качестве аргумента путь к каталогу и ищет файлы в этом каталоге и всех его подкаталогах.

Она использует функцию os.listdir() для получения имен всех файлов и каталогов в указанном каталоге, а затем – функцию os.path.isdir() для проверки, является ли данный файл или каталог каталогом. Если это каталог, функция вызывает себя рекурсивно для поиска файлов с определенным расширением в этом каталоге. Если это файл, функция проверяет расширение и выводит имя файла, если оно заканчивается целевым расширением.

Давайте вызовем эту функцию, чтобы увидеть ее в действии.

Пример

Продолжим работу с папкой проекта Example со следующей структурой:

.
├── Data
│   └── ages.txt
│   └── numbers.txt
├── Images
│   └── image.png
├── Samples
│   └── codes.txt
│   └── readme.txt
├── finder.py
├── names.txt
└── values.txt

Наша цель – найти в папке и ее подпапках все файлы, имеющие расширение .txt, выполнив Python-скрипт в файле finder.py.

Для этого скопируем функцию find_files из предыдущего раздела в файл finder.py. Вызовем функцию, задав в качестве параметров текущий каталог и .txt:

find_files('.', '.txt')

Вывод:

./Data/numbers.txt
./Data/ages.txt
./Samples/readme.txt
./Samples/codes.txt
./names.txt
./values.txt

Потрясающе! На этот раз функция нашла текстовые файлы не только на том же уровне, что и файл Python, но и во вложенных папках.

Несмотря на то, что этот пример дает отличную практику работы с рекурсией в Python, существует более простая альтернатива для поиска файлов.

3. Рекурсивный поиск файлов при помощи os.walk

Самый простой способ рекурсивного поиска всех файлов с определенным расширением в папке и ее подпапках – это использование функции os.walk.

Вот как может выглядеть ее вызов:

import os

for root, dirs, files in os.walk('/path/to/directory'):
    for file in files:
        if file.endswith('.someextension'):
            print(os.path.join(root, file))

Этот код импортирует модуль os, который предоставляет функции для взаимодействия с операционной системой. Затем он использует функцию os.walk() для рекурсивного перебора всех каталогов и подкаталогов внутри указанного каталога ('/path/to/directory').

Для каждого каталога в дереве он устанавливает три переменные: root, dirs и files. Переменная root содержит путь к текущему каталогу, dirs – список подкаталогов в этом каталоге, а files – список файлов в текущем каталоге.

Затем программа перебирает список файлов в текущем каталоге и проверяет, заканчивается ли файл указанным расширением. Если да, то печатает полный путь к этому файлу с помощью функции os.path.join(). Это позволяет найти все файлы с указанным расширением во всем дереве каталогов, а не только в текущем каталоге.

Это удобная замена довольно длинной рекурсии из предыдущего раздела.

Пример

Давайте продолжим использовать структуру проекта, которую вы уже видели в этом руководстве, и найдем все файлы .txt в папке и ее подпапках.

.
├── Data
│   └── ages.txt
│   └── numbers.txt
├── Images
│   └── image.png
├── Samples
│   └── codes.txt
│   └── readme.txt
├── finder.py
├── names.txt
└── values.txt

Для этого изменим ранее представленный код так, чтобы он был нацелен на текущую папку и показывал только файлы с расширением .txt:

import os

for root, dirs, files in os.walk('.'):
    for file in files:
        if file.endswith('.txt'):
            print(os.path.join(root, file))

Запуск finder.py с приведенным выше кодом показывает все файлы с расширением .txt:

% python3 finder.py
./names.txt
./values.txt
./Data/numbers.txt
./Data/ages.txt
./Samples/readme.txt
./Samples/codes.txt

Заключение

Сегодня вы узнали, как найти файлы с определенным расширением в Python. В качестве домашнего задания используйте функцию os.walk(), чтобы рекурсивно пройтись по папкам и подпапкам и найти все файлы с определенным расширением.

Спасибо за внимание. Успешного кодинга!

Перевод статьи Artturi Jalli “Python Find Files with Extension (.txt): A Step-by-Step Guide”