Получить отфильтрованный список файлов в каталоге
-
19-09-2019 - |
Вопрос
Я пытаюсь получить список файлов в каталоге, используя Python, но мне не нужен список ВСЕХ файлов.
По сути, я хочу иметь возможность делать что-то вроде следующего, но используя Python и не выполняя ls.
ls 145592*.jpg
Если для этого нет встроенного метода, в настоящее время я подумываю о написании цикла for для перебора результатов os.listdir()
и добавить все соответствующие файлы в новый список.
Однако в этом каталоге много файлов, и поэтому я надеюсь, что существует более эффективный метод (или встроенный метод).
Решение
Другие советы
glob.glob()
это определенно способ сделать это (согласно Игнасио).Однако, если вам нужно более сложное сопоставление, вы можете сделать это с помощью понимания списка и re.match()
, что-то вроде этого:
files = [f for f in os.listdir('.') if re.match(r'[0-9]+.*\.jpg', f)]
Более гибкий, но, как вы заметили, менее эффективный.
Будь проще:
import os
relevant_path = "[path to folder]"
included_extensions = ['jpg','jpeg', 'bmp', 'png', 'gif']
file_names = [fn for fn in os.listdir(relevant_path)
if any(fn.endswith(ext) for ext in included_extensions)]
Я предпочитаю эту форму понимания списков, потому что она хорошо читается на английском языке.
Я прочитал четвертую строку так:Для каждого fn в os.listdir для моего пути укажите только те, которые соответствуют любому из моих включенных расширений.
Начинающим программистам на Python может быть трудно привыкнуть к использованию списков для фильтрации, и это может потребовать некоторых затрат памяти для очень больших наборов данных, но для перечисления каталогов и других простых задач фильтрации строк, списковые генераторы приводят к более чистому результату. документируемый код.
Единственное, что касается этой конструкции, это то, что она не защищает вас от ошибки при передаче строки вместо списка.Например, если вы случайно преобразуете строку в список и в конечном итоге проверяете все символы строки, вы можете получить множество ложных срабатываний.
Но лучше иметь проблему, которую легко решить, чем решение, которое трудно понять.
Другой вариант:
>>> import os, fnmatch
>>> fnmatch.filter(os.listdir('.'), '*.py')
['manage.py']
используйте os.walk для рекурсивного просмотра ваших файлов
import os
root = "/home"
pattern = "145992"
alist_filter = ['jpg','bmp','png','gif']
path=os.path.join(root,"mydir_to_scan")
for r,d,f in os.walk(path):
for file in f:
if file[-3:] in alist_filter and pattern in file:
print os.path.join(root,file)
Предварительный код
import glob
import fnmatch
import pathlib
import os
pattern = '*.py'
path = '.'
Решение 1 - используйте "глобус"
# lookup in current dir
glob.glob(pattern)
In [2]: glob.glob(pattern)
Out[2]: ['wsgi.py', 'manage.py', 'tasks.py']
Решение 2 - используйте "os" + "fnmatch"
Вариант 2.1 - Поиск в текущем каталоге
# lookup in current dir
fnmatch.filter(os.listdir(path), pattern)
In [3]: fnmatch.filter(os.listdir(path), pattern)
Out[3]: ['wsgi.py', 'manage.py', 'tasks.py']
Вариант 2.2 - Рекурсивный поиск
# lookup recursive
for dirpath, dirnames, filenames in os.walk(path):
if not filenames:
continue
pythonic_files = fnmatch.filter(filenames, pattern)
if pythonic_files:
for file in pythonic_files:
print('{}/{}'.format(dirpath, file))
Результат
./wsgi.py
./manage.py
./tasks.py
./temp/temp.py
./apps/diaries/urls.py
./apps/diaries/signals.py
./apps/diaries/actions.py
./apps/diaries/querysets.py
./apps/library/tests/test_forms.py
./apps/library/migrations/0001_initial.py
./apps/polls/views.py
./apps/polls/formsets.py
./apps/polls/reports.py
./apps/polls/admin.py
Решение 3 - используйте "pathlib"
# lookup in current dir
path_ = pathlib.Path('.')
tuple(path_.glob(pattern))
# lookup recursive
tuple(path_.rglob(pattern))
Примечания:
- Протестировано на Python 3.4
- Модуль "pathlib" был добавлен только в Python 3.4
- В Python 3.5 добавлена функция рекурсивного поиска с помощью glob.glob https://docs.python.org/3.5/library/glob.html#glob.glob.Поскольку на моем компьютере установлен Python 3.4, я это не тестировал.
Фильтровать с помощью glob
модуль:
Импортировать глобальный
import glob
Дикие карты:
files=glob.glob("data/*")
print(files)
Out:
['data/ks_10000_0', 'data/ks_1000_0', 'data/ks_100_0', 'data/ks_100_1',
'data/ks_100_2', 'data/ks_106_0', 'data/ks_19_0', 'data/ks_200_0', 'data/ks_200_1',
'data/ks_300_0', 'data/ks_30_0', 'data/ks_400_0', 'data/ks_40_0', 'data/ks_45_0',
'data/ks_4_0', 'data/ks_500_0', 'data/ks_50_0', 'data/ks_50_1', 'data/ks_60_0',
'data/ks_82_0', 'data/ks_lecture_dp_1', 'data/ks_lecture_dp_2']
Расширение фитера .txt
:
files = glob.glob("/home/ach/*/*.txt")
Один персонаж
glob.glob("/home/ach/file?.txt")
Диапазоны номеров
glob.glob("/home/ach/*[0-9]*")
Алфавитные диапазоны
glob.glob("/home/ach/[a-c]*")
вам также может понравиться более высокоуровневый подход (я реализовал и упаковал как инструменты поиска):
from findtools.find_files import (find_files, Match)
# Recursively find all *.txt files in **/home/**
txt_files_pattern = Match(filetype='f', name='*.txt')
found_files = find_files(path='/home', match=txt_files_pattern)
for found_file in found_files:
print found_file
может быть установлен с
pip install findtools
import os
dir="/path/to/dir"
[x[0]+"/"+f for x in os.walk(dir) for f in x[2] if f.endswith(".jpg")]
Это даст вам список файлов jpg с полным путем.Вы можете заменить x[0]+"/"+f
с f
только для имен файлов.Вы также можете заменить f.endswith(".jpg")
с любым строковым условием, которое вы пожелаете.
Имена файлов с расширениями «jpg» и «png» в «path/to/images»:
import os
accepted_extensions = ["jpg", "png"]
filenames = [fn for fn in os.listdir("path/to/images") if fn.split(".")[-1] in accepted_extensions]
Вы можете использовать библиотека пути который доступен в стандартной библиотеке Python версии 3.4 и выше.
from pathlib import Path
files = [f for f in Path.cwd().iterdir() if f.match("145592*.jpg")]
Вы можете использовать subprocess.check_ouput() как
import subprocess
list_files = subprocess.check_output("ls 145992*.jpg", shell=True)
Конечно, строка между кавычками может быть чем угодно, что вы хотите выполнить в оболочке и сохранить вывод.