glob Python

Содержание
Введение
Пример
Поиск по шаблону
Поиск по нескольким директориям
Поиск по вложенным директориям
Поиск скрытых файлов
iglob
Похожие статьи

Введение

В этой статье вы узнаете как работать с несколькими файлами одновременно с помощью glob.

Модуль glob находит все имена путей, соответствующие указанному шаблону, в соответствии с правилами, используемыми оболочкой Unix , хотя результаты возвращаются в произвольном порядке.

Расширение тильдой не выполняется, но *, ? и диапазоны символов, выраженные с помощью [], будут правильно сопоставлены. Это делается с помощью функций os.scandir() и fnmatch.fnmatch() совместно, а не путем фактического вызова подоболочки.

Оффициальная документация

Пример

Предположим, что мы находимся в директории glob_ex:

glob_ex/ └── sample_files ├── it.txt ├── testing.txt └── travel.txt

# glob_ex.py import glob files = glob.glob("./sample_files/*.txt") print(files)

python glob_ex.py

['./sample_files/it.txt', './sample_files/travel.txt']

Поиск по шаблону

Примеры других шаблонов для поиска

… files = glob.glob("./sample_files/?.txt") print(files) files = glob.glob("./sample_files/??.txt") print(files) files = glob.glob("./sample_files/t*.txt") print(files)

['./sample_files/it.txt'] ['./sample_files/it.txt'] ['./sample_files/testing.txt', './sample_files/travel.txt']

# starts with character from the range files = glob.glob("./sample_files/[it]*.txt") print(files) files = glob.glob("./sample_files/[ghi]*.txt") print(files) files = glob.glob("./sample_files/[rst]*.txt") print(files) files = glob.glob("./sample_files/[abc]*.txt") print(files)

['./sample_files/it.txt', './sample_files/testing.txt', './sample_files/travel.txt'] ['./sample_files/it.txt'] ['./sample_files/testing.txt', './sample_files/travel.txt'] []

… # starts with character not from the range files = glob.glob("./sample_files/[!i]*.txt") print(files) files = glob.glob("./sample_files/[!t]*.txt") print(files) files = glob.glob("./sample_files/[!abc]*.txt") print(files)

['./sample_files/testing.txt', './sample_files/travel.txt'] ['./sample_files/it.txt'] ['./sample_files/it.txt', './sample_files/testing.txt', './sample_files/travel.txt']

# glob_ex.py import glob files = glob.glob("./sample_files/*.txt") for file in files: print(file) with open(file, "r") as f: lines = f.readlines() for line in lines: print(line, end = "")

python glob_ex.py

./sample_files/it.txt beget.com kaspersky.com ./sample_files/testing.txt www.urn.su www.otus.ru ./sample_files/travel.txt aviasales.com booking.com

Поиск по нескольким директориям

Обновим структуру проекта

glob_ex/ ├── glob_ex.py ├── heihei │ ├── Finland.html │ ├── Spain.html │ └── Sweden.html └── topbicycle ├── forward.html ├── stark.html └── stels.html

Чтобы искать сразу в нескольких директориях внутри корневой нужно использовать **.

Если версия вашего Python 3.10 или выше рекомендую указать корневую директорию с помощью root_dir

import glob files = glob.glob("**/*.html", root_dir="/mnt/c/Users/Andrei/glob_ex/" ) print(files)

['heihei/Finland.html', 'heihei/Spain.html', 'heihei/Sweden.html', 'topbicycle/forward.html', 'topbicycle/stark.html', 'topbicycle/stels.html']

root_dir нужно указывать в соответсвии с окружением в котором запускается Python.

В данном примере Python запущен в WSL2 , поэтому перед /c указан /mnt.

/mnt/c/Users/Andrei/glob_ex/

В Git Bash путь будет начинаться сразу с /

/c/Users/Andrei/glob_ex/

В полноценном Linux скорее всего с /home

/home/andrei/glob_ex/

В Windows , например, в PowerShell этот же путь будет выглядеть как

C:\Users\Andrei\glob_ex

Поиск по вложенным директориям

Усложним структуру проекта, добавив вложенные директории

glob_ex/ ├── glob_ex.py ├── heihei │ ├── Armenia │ │ ├── .hidden.html │ │ ├── holidays │ │ │ ├── easter.html │ │ │ └── sargis.html │ │ └── index.html │ ├── Finland.html │ ├── Spain.html │ └── Sweden.html └── topbicycle ├── forward.html ├── stark.html └── stels.html

Если теперь запустить тот же скрипт он не найдёт файлы в новой поддиректории Armenia.

['heihei/Finland.html', 'heihei/Spain.html', 'heihei/Sweden.html', 'topbicycle/forward.html', 'topbicycle/stark.html', 'topbicycle/stels.html']

Параметр recursive регулирует поиск во вложенных директориях. Если установить recursive=True то поиск будет осуществляться по всем поддиректориям.

import glob files = glob.glob("**/*.html", root_dir="/mnt/c/Users/Andrei/glob_ex/", recursive=True ) print(files)

['heihei/Finland.html', 'heihei/Spain.html', 'heihei/Sweden.html', 'heihei/Armenia/index.html', 'heihei/Armenia/holidays/easter.html', 'heihei/Armenia/holidays/sargis.html', 'topbicycle/forward.html', 'topbicycle/stark.html', 'topbicycle/stels.html']

Теперь скрипт находит все файлы из поддиректории Armenia, соответствующие шаблону.

Поиск скрытых файлов

Если у вас Python версии 3.11 и выше, то можно использовать опцию include_hidden, с помощью которой в директории Armenia можно найти файл .hidden.html

Напоминаю, что новую структуру проекта можно изучить здесь

О том как установить свежую версию Python в Linux или WSL вы можете прочитать в статье «Установка Python в Linux»

import glob files = glob.glob("**/*.html", root_dir="/mnt/c/Users/Andrei/glob_ex/", recursive=True, include_hidden=True ) print(files)

['heihei/Finland.html', 'heihei/Spain.html', 'heihei/Sweden.html', 'heihei/Armenia/.hidden.html', 'heihei/Armenia/index.html', 'heihei/Armenia/holidays/easter.html', 'heihei/Armenia/holidays/sargis.html', 'topbicycle/forward.html', 'topbicycle/stark.html', 'topbicycle/stels.html']

Со всеми этими опциями можно применять те же самые шаблоны, что и раньше.

import glob files = glob.glob("**/[st]*.html", root_dir="/mnt/c/Users/Andrei/glob_ex/", recursive=True, include_hidden=True ) print(files)

['heihei/Armenia/holidays/sargis.html', 'topbicycle/stark.html', 'topbicycle/stels.html']

import glob files = glob.glob("**/[St]*.html", root_dir="/mnt/c/Users/Andrei/glob_ex/", recursive=True, include_hidden=True ) print(files)

['heihei/Spain.html', 'heihei/Sweden.html']

iglob

Для работы с большими объемами данных может пригодится метод iglob, который возвращает итератор

import glob globs = glob.iglob("**/*.html",             root_dir="/mnt/c/Users/Andrei/glob_ex/",             recursive=True,             include_hidden=True         ) print(globs) print("type(globs): ", type(globs)) print("globs.__next__: ", globs.__next__) print("type(globs.__next__): ", type(globs.__next__)) print(globs.__next__()) print(globs.__next__()) # another way to call next() print(next(globs)) print(next(globs))

<itertools.chain object at 0x7fce30e36ad0> type(globs): <class 'itertools.chain'> globs.__next__: <method-wrapper '__next__' of itertools.chain object at 0x7fce30e36ad0> type(globs.__next__): <class 'method-wrapper'> heihei/Finland.html heihei/Spain.html heihei/Sweden.html heihei/Armenia/.hidden.html

Обойти все файлы можно с помощью цикла for

Найдём все .py файлы в директории python. Для большей наглядности вывода используем функцию enumerate()

import glob globs = glob.iglob("**/*.py",             root_dir="/mnt/c/Users/Andrei/python/",             recursive=True,             include_hidden=True         ) for i, file in enumerate(globs, 2):     print(i, file, sep=': ')

2: copy_ex.py 3: dict_ex.py 4: dir_ex.py 5: pass_arg.py 6: random_gen.py 7: random_gen2.py 8: tcompl_ex.py 9: glob_ex/glob_ex.py 10: glob_ex/glob_ex1.py 11: glob_ex/glob_ex3.py 12: glob_ex/iglob_ex.py 13: Python-3.11.3/python-config.py 14: Python-3.11.3/python.exe-gdb.py 15: Python-3.11.3/setup.py 16: Python-3.11.3/build/lib.linux-x86_64-3.11/_sysconfigdata__linux_x86_64-linux-gnu.py 17: Python-3.11.3/Doc/conf.py … 2934: venv/Lib/site-packages/setuptools/_vendor/tomli/__init__.py 2935: venv/Lib/site-packages/_distutils_hack/override.py 2936: venv/Lib/site-packages/_distutils_hack/__init__.py