Вопрос

Я пытаюсь получить список файлов в каталоге, используя 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']

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

используйте 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))

Примечания:

  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, я это не тестировал.

Фильтровать с помощью 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) 

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top