Получить отфильтрованный список файлов в каталоге

Я пытаюсь получить список файлов в каталоге с помощью Python, но мне не нужен список ВСЕХ файлов.

То, что я в основном хочу, это способность делать что-то вроде следующего, но использовать Python и не выполнять ls.

ls 145592*.jpg

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

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

+239
источник поделиться
12 ответов

glob.glob() - это определенно способ сделать это (согласно Ignacio). Однако, если вам нужно более сложное совпадение, вы можете сделать это со списком и re.match(), примерно так:

files = [f for f in os.listdir('.') if re.match(r'[0-9]+.*\.jpg', f)]

Более гибкий, но, как вы заметили, менее эффективный.

+113
источник
другие ответы

Связанные вопросы


Похожие вопросы

Будь проще:

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 может быть трудно привыкнуть к использованию списочных представлений для фильтрации, и это может иметь некоторые накладные расходы памяти для очень больших наборов данных, но для перечисления каталога и других простых задач фильтрации строк, списочные понимания приводят к более чистому документируемый код.

Единственное, что есть в этом дизайне, это то, что он не защищает вас от ошибки при передаче строки вместо списка. Например, если вы случайно конвертируете строку в список и заканчиваете проверкой всех символов строки, вы можете получить массу ложных срабатываний.

Но лучше иметь проблему, которую легко решить, чем решение, которое трудно понять.

+42
источник

Другая опция:

>>> import os, fnmatch
>>> fnmatch.filter(os.listdir('.'), '*.py')
['manage.py']

https://docs.python.org/3/library/fnmatch.html

+33
источник

использовать 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)
+8
источник

Предварительный код

import glob
import fnmatch
import pathlib
import os

pattern = '*.py'
path = '.'

Решение 1 - используйте "glob"

# 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))

Примечание:

  1. Проверено на Python 3.4
  2. Модуль "pathlib" был добавлен только в Python 3.4
  3. В Python 3.5 добавлена функция рекурсивного поиска с glob.glob https://docs.python.org/3.5/library/glob.html#glob.glob. Так как моя машина установлена с Python 3.4, я не проверял это.
+8
источник

Фильтр с модулем glob:

Импорт глобуса

import glob

Wild Cards:

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']

Расширение Fiter .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]*")
+6
источник

вам также может понравиться более высокоуровневый подход (я реализовал и упаковал как findtools):

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
+2
источник
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") любым строковым условием.

+2
источник

Имена файлов с расширениями "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]
+1
источник

Вы можете использовать pathlib, который доступен в стандартной библиотеке Python 3.4 и выше.

from pathlib import Path

files = [f for f in Path.cwd().iterdir() if f.match("145592*.jpg")]
0
источник

Вы можете использовать subprocess.check_ouput() как

import subprocess

list_files = subprocess.check_output("ls 145992*.jpg", shell=True) 

Конечно, строка между кавычками может быть тем, что вы хотите выполнить в оболочке, и сохранить вывод.

-1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос