Python поиск файлов по расширению
Как я могу найти все файлы в каталоге с расширением .txt в python?
Вы можете использовать glob :
или если вы хотите перемещаться по каталогу, используйте os.walk :
Что-то вроде этого должно выполнять работу
Что-то вроде этого будет работать:
Или с генераторами:
Здесь больше версий, которые дают несколько разные результаты:
glob.iglob()
glob.glob1()
fnmatch.filter()
Вы можете просто использовать pathlib glob 1 :
Если вы хотите, чтобы он был рекурсивным, вы можете использовать .glob('**/*.txt)
1 Модуль pathlib был включен в стандартную библиотеку в python 3.4. Но вы можете установить back-ports этого модуля даже в более старых версиях Python (например, используя conda или pip ): pathlib и pathlib2 .
У Python есть все инструменты для этого:
Этот код упрощает мою жизнь.
Чтобы получить все имена файлов .txt внутри папки 'dataPath' в виде списка на языке Pythonic
Python v3. 5+
Быстрый метод с использованием os.scandir в рекурсивной функции. Поиск всех файлов с указанным расширением в папке и подпапках.
Обновление апреля 2019
Если вы ищете в каталогах, которые содержат файлы 10 000, добавление в список становится неэффективным. "Сдача" результатов - лучшее решение. Я также включил функцию для преобразования вывода в Pandas Dataframe.
Вы можете попробовать этот код
Я сделал тест (Python 3.6.4, W7x64), чтобы узнать, какое решение является самым быстрым для одной папки, а не подкаталогами, чтобы получить список полных путей к файлам с определенным расширением.
Чтобы сделать это коротко, для этой задачи os.listdir() является самым быстрым и равен 1.7x быстрее, чем следующее: os.walk() (с разрывом!), 2.7x быстрее, чем pathlib , в 3,2 раза быстрее чем os.scandir() и 3,3 раза быстрее, чем glob .
Имейте в виду, что эти результаты будут меняться, когда вам потребуются рекурсивные результаты. Если вы скопируете/вставьте один из методов ниже, добавьте .lower() в противном случае .EXT не будет найден при поиске .ext.
Для меня. Это классика.
Я предлагаю вам использовать fnmatch и верхний метод. Таким образом вы можете найти любое из следующего:
Чтобы получить массив имен файлов ".txt" из папки "данные" в том же каталоге, я обычно использую эту простую строку кода:
Как я могу найти все файлы в каталоге с расширением .txt в python?
31 ответ
Вы можете использовать glob :
или если вы хотите перемещаться по каталогу, используйте os.walk :
Используя решение № 2, как бы вы создали файл или список с этой информацией? @ ghostdog74: По моему мнению, было бы более уместно написать for file in f чем для for files in f поскольку в переменной есть одно имя файла. Еще лучше было бы изменить f на files и тогда цикл for мог бы стать for file in files . @ ghostdog74: есть ли разница в производительности между этими параметрами? file @martineau является зарезервированным словом и не может использоваться в качестве переменной. тем не менее, возможно, более понятно сделать for f in files и переключить остальную часть кода, чтобы f был единственным файлом, а файлы - списком @computermacgyver: Нет, file - это не зарезервированное слово, а просто имя предопределенной функции, поэтому вполне возможно использовать его в качестве имени переменной в вашем собственном коде. Хотя это правда, что обычно следует избегать подобных коллизий, file - это особый случай, потому что вряд ли когда-либо понадобится его использовать, поэтому его часто считают исключением из руководства. Если вы не хотите этого делать, PEP8 рекомендует добавить к таким именам единичное подчеркивание, например, file_ , с которым, как вы согласитесь, все еще вполне читабельно. Спасибо, Мартино, ты абсолютно прав. Я слишком быстро спешил с выводами. Действительно крутой ответ, вы можете заменить r, d, f на r, _, f, чтобы избежать объявления неиспользуемых переменных. Я упал на это для файла в предложении е в моей голове тоже. Возможно, для fileName в f было бы лучше, так как мы перебираем список имен файлов, а не файловых объектов. мои пять центов - Python glob (), вероятно, отличается от системного glob. когда системный глобус завершается с ошибкой «Список аргументов слишком длинный», python glob работает нормально. @computermacgyver - Согласно pep8, вы должны добавить символ подчеркивания _ в конец имени, если это в противном случае скрыло бы встроенную функцию (если, конечно, вы не намерены скрывать встроенную функцию). Так что в этом случае вы должны использовать for file_ in files . Конечно, или f тоже работает, и это обычный выбор имени переменной для файлов в Python, так что я думаю, что это приемлемо, хотя, как правило, следует избегать очень коротких имен переменных, подобных этому. Как файлы могут быть получены ?? Мой вопрос: например, если в каталоге было n файлов с расширением .txt и какой файл был выбран первым при запуске соответствующей функции . На основании размера файла или любых других критериев? Я не знаю, как получить это . Если мне нужен файл с наибольшим размером хранилища, то как извлечь это в первую очередь ?? @Merlin, перед циклом for, инициализируйте пустой список, скажем, fileList = [], а затем замените последний оператор цикла на fileList.append (os.path.join (root, file)). Я нашел text_files = [f for f in os.listdir("/mydir") if os.path.isfile(os.path.join("/mydir", f)) and f.endswith(".txt")] работать быстрее, чем второй вариант .. os.listdir также перечисляет каталоги, поэтому, если какой-нибудь жестокий человек назовет каталог blabla.txt, он также покажет этот каталог (не только файл .txt). Используйте isfile, чтобы убедиться, что это файл. @ ghostdog74 Эй, это великолепно. Работал хорошо для меня. Спасибо! Это не только просто, но и без учета регистра. (По крайней мере, это на Windows, как и должно быть. Я не уверен насчет других ОС.) Помните, что glob не может найти файлы рекурсивно, если ваш питон меньше 3.5. больше информации лучшая часть вы можете использовать тест регулярного выражения * .txtЧто-то вроде этого должно выполнять работу
+1 для именования ваших переменных root, dirs, files вместо r, d, f . Гораздо более читабельноЧто-то вроде этого будет работать:
Или с генераторами:
Здесь больше версий, которые дают несколько разные результаты:
glob.iglob()
glob.glob1()
fnmatch.filter()
Для любопытных, glob1() - это вспомогательная функция в модуле glob которого нет в документации по Python. Есть несколько встроенных комментариев, описывающих, что он делает в исходном файле, см. . /Lib/glob.py Спасибо, это хорошая дополнительная информация для принятия решения о том, использовать ли недокументированную приватную функцию в модуле. ;-) Вот еще немного. Версия Python 2.7 имеет длину всего 12 строк и выглядит так, как будто ее легко извлечь из модуля glob .Вы можете просто использовать pathlib glob 1 :
Если вы хотите, чтобы он был рекурсивным, вы можете использовать .glob('**/*.txt)
1 Модуль pathlib был включен в стандартную библиотеку в python 3.4. Но вы можете установить back-ports этого модуля даже в более старых версиях Python (например, используя conda или pip ): pathlib и pathlib2 .
@Roman Да, это была просто демонстрация того, что может сделать pathlib , и я уже включил требования к версии Python. :) Но если ваш подход еще не опубликован, почему бы просто не добавить его в качестве другого ответа? да, размещение ответа дало бы мне лучшие возможности форматирования, безусловно. Я постет там, потому что думаю, что это более подходящее место для этого.У Python есть все инструменты для этого:
Этот код упрощает мою жизнь.
Чтобы получить все имена файлов .txt внутри папки 'dataPath' в виде списка на языке Pythonic
Я сделал тест (Python 3.6.4, W7x64), чтобы узнать, какое решение является самым быстрым для одной папки, а не подкаталогами, чтобы получить список полных путей к файлам с определенным расширением.
Многим из нас знакома ситуация, когда компьютер оказывался завален тоннами беспорядочных файлов. Только что вы открывали большой zip-архив, спустя мгновение – файлы повсюду в этой директории, вперемешку с важными документами. Наверняка приходилось мучительно скучно сортировать эту свалку вручную? Чтобы облегчить подобные задачи, мы сейчас погрузимся в «умную» работу с файлами при помощи Python.
Итак, приступим, вооружившись Python версии 3.4 или выше. Сначала пройдемся по модулю OS, а по ходу дела познакомимся еще с несколькими. Всё, что мы будем использовать, доступно в Python «с коробки», так что ничего дополнительно устанавливать не потребуется.
Генератор случайных файлов
Чтобы поиграться с файлами, мы сгенерируем их случайным образом в директории RandomFiles . Создайте файл create_random_files.py в папке ManageFiles . Вот что должно получиться:
Готово? Теперь поместите в файл следующий код, и перейдем к его рассмотрению:
Начиная с Python 3.4 мы получили pathlib, нашу маленькую волшебную палочку. Также мы импортируем функцию random для генерации случайных чисел, но ее мы посмотрим в действии чуть ниже.
Сперва создадим список файловых расширений для формирования названий файлов. Не стесняйтесь добавить туда свои варианты.
Далее мы переходим в папку RandomFiles и запускаем цикл. В нем мы просто говорим: возьми каждый элемент list_of_extensions и сделай с ним кое-что во внутреннем цикле 20 раз.
Теперь пришло время для импортированной функции random . Используем ее для производства случайных чисел от 1 до 50. Это просто не очень творческий способ побыстрее дать названия нашим тестовым файлам: к сгенерированному числу добавим расширение файла и получим что-то вроде 23.txt или 14.txt . И так 20 раз для каждого расширения. В итоге образуется беспорядок, достаточный для того, чтобы его было лень сортировать вручную.
Итак, запустим наш генератор хаоса через терминал.
Поздравляю, теперь у нас полная папка неразберихи. Будем распутывать.
В той же директории, где create_random_files.py , создадим файл clean_up.py и поместим туда следующий код.
Способ 1
Для этого импортируем еще две библиотеки: shutil и glob. Первая поможет перемещать файлы, а вторая – находить и систематизировать. Но обо всем по порядку.
Для начала получим список всех файлов в директории.
Здесь мы предполагаем, что у нас нет ни малейшего понятия о том, какие именно файлы лежат в этой папке. Вместо того, чтобы вписывать все расширения вручную и использовать лестницу инструкций if или switch, мы желаем, чтобы программа сама просмотрела каталог и определила, на какие типы можно разделить его содержание. Что, если бы там были файлы с десятками расширений или логи? Вы бы стали описывать их вручную?
Получив список всех файлов, мы заходим в еще один цикл, чтобы извлечь расширения названий.
Сейчас наша переменная our_file выглядит как-нибудь так: 5.docx . Когда разделим ее, получим следующее:
Мы возьмем отсюда второй элемент по индексу [1], то есть .docx . Ведь по индексу [0] у нас располагается 5 .
Таким образом, у нас имеется список всех файловых расширений в папке, в том числе повторяющихся. Чтобы оставить только уникальные элементы, преобразуем его во множество. К примеру, если бы этот список состоял исключительно из .docx , повторяющегося снова и снова, то в set остался бы всего один элемент.
Заметим, что в списке типов файлов каждое расширение содержит . в начале. Если мы назовем так папки на UNIX-системе, то они будут скрытыми, что не входит в наши намерения.
Поэтому, итерируя по нашему множеству, мы заменяем точку на пустую строку. И создаем папку с полученным названием.
Но чтобы переместить файлы, нам все еще нужно расширение .docx .
Этим попросту отбираем все файлы, оканчивающиеся расширением .docx . Заметьте, что в f'*.') нет пробелов.
Символ подстановки * обозначает, что подходит любое имя, если оно заканчивается на .docx . Поскольку мы уже включили точку в поиск, мы используем [1:], что значит «все после первого символа». В нашем примере это docx .
Что дальше? Перемещаем любые файлы с данным расширением в директорию с тем же названием.
Таким образом, как только в цикле создана папка для первого попавшегося файла с данным расширением, все последующие файлы будут отправлены в нее же. Все будет сгруппировано без повторения каталогов.
Способ 2
В качестве хитрого способа создать список в одну строку можно использовать генераторы.
Оба варианта сработают, и все ваши файлы будут отсортированы по расширению.
Вот и все. Если вам когда-либо понадобится отсортировать файлы таким образом, вы сэкономите немало времени 😊. Код упражнения доступен здесь.
Python становится все популярнее благодаря относительной простоте изучения, универсальности и другим преимуществам. Правда, у начинающих разработчиков нередко возникают проблемы при работе с файлами и файловой системой. Просто потому, что они знают не все команды, которые нужно знать.
Эта статья предназначена как раз для начинающих разработчиков. В ней описаны 8 крайне важных команд для работы с файлами, папками и файловой системой в целом. Все примеры из этой статьи размещены в Google Colab Notebook (ссылка на ресурс — в конце статьи).
Показать текущий каталог
Самая простая и вместе с тем одна из самых важных команд для Python-разработчика. Она нужна потому, что чаще всего разработчики имеют дело с относительными путями. Но в некоторых случаях важно знать, где мы находимся.
Относительный путь хорош тем, что работает для всех пользователей, с любыми системами, количеством дисков и так далее.
Так вот, для того чтобы показать текущий каталог, нужна встроенная в Python OS-библиотека:
Ее легко запомнить, так что лучше выучить один раз, чем постоянно гуглить. Это здорово экономит время.
Имейте в виду, что я использую Google Colab, так что путь /content является абсолютным.
Проверяем, существует файл или каталог
Прежде чем задействовать команду по созданию файла или каталога, стоит убедиться, что аналогичных элементов нет. Это поможет избежать ряда ошибок при работе приложения, включая перезапись существующих элементов с данными.
Функция os.path.exists () принимает аргумент строкового типа, который может быть либо именем каталога, либо файлом.
В случае с Google Colab при каждом запуске создается папка sample_data. Давайте проверим, существует ли такой каталог. Для этого подойдет следующий код:
Эта же команда подходит и для работы с файлами:
Если папки или файла нет, команда возвращает false.
Объединение компонентов пути
В предыдущем примере я намеренно использовал слеш "/" для разделителя компонентов пути. В принципе это нормально, но не рекомендуется. Если вы хотите, чтобы ваше приложение было кроссплатформенным, такой вариант не подходит. Так, некоторые старые версии ОС Windows распознают только слеш "\" в качестве разделителя.
Но не переживайте, Python прекрасно решает эту проблему благодаря функции os.path.join (). Давайте перепишем вариант из примера в предыдущем пункте, используя эту функцию:
Создание директории
Ну а теперь самое время создать директорию с именем test_dir внутри рабочей директории. Для этого можно использовать функцию
os.mkdir():
Давайте посмотрим, как это работает на практике.
Если же мы попытаемся создать каталог, который уже существует, то получим исключение.
Именно поэтому рекомендуется всегда проверять наличие каталога с определенным названием перед созданием нового:
Еще один совет по созданию каталогов. Иногда нам нужно создать подкаталоги с уровнем вложенности 2 или более. Если мы все еще используем os.mkdir (), нам нужно будет сделать это несколько раз. В этом случае мы можем использовать os.makedirs (). Эта функция создаст все промежуточные каталоги так же, как флаг mkdir -p в системе Linux:
Вот что получается в результате.
Показываем содержимое директории
Еще одна полезная команда — os.listdir(). Она показывает все содержимое каталога.
Команда отличается от os.walk (), где последний рекурсивно показывает все, что находится «под» каталогом. os.listdir () намного проще в использовании, потому что просто возвращает список содержимого:
В некоторых случаях нужно что-то более продвинутое — например, поиск всех CSV-файлов в каталоге «sample_data». В этом случае самый простой способ — использовать встроенную библиотеку glob:
Перемещение файлов
Самое время попробовать переместить файлы из одной папки в другую. Рекомендованный способ — еще одна встроенная библиотека shutil.
Сейчас попробуем переместить все CSV-файлы из директории «sample_data» в директорию «test_dir». Ниже — пример кода для выполнения этой операции:
Кстати, есть два способа выполнить задуманное. Например, мы можем использовать библиотеку OS, если не хочется импортировать дополнительные библиотеки. Как os.rename, так и os.replace подходят для решения задачи.
Но обе они недостаточно «умные», чтобы позволить перемесить файлы в каталог.
Чтобы все это работало, нужно явно указать имя файла в месте назначения. Ниже — код, который это позволяет сделать:
Здесь функция os.path.basename () предназначена для извлечения имени файла из пути с любым количеством компонентов.
Другая функция, os.replace (), делает то же самое. Но разница в том, что os.replace () не зависит от платформы, тогда как os.rename () будет работать только в системе Unix / Linux.
Еще один минус — в том, что обе функции не поддерживают перемещение файлов из разных файловых систем, в отличие от shutil.
Поэтому я рекомендую использовать shutil.move () для перемещения файлов.
Копирование файлов
Аналогичным образом shutil подходит и для копирования файлов по уже упомянутым причинам.
Если нужно скопировать файл README.md из папки «sample_data» в папку «test_dir», поможет функция shutil.copy():
Удаление файлов и папок
Теперь пришел черед разобраться с процедурой удаления файлов и папок. Нам здесь снова поможет библиотека OS.
Когда нужно удалить файл, нужно воспользоваться командой os.remove():
Если требуется удалить каталог, на помощь приходит os.rmdir():
Однако он может удалить только пустой каталог. На приведенном выше скриншоте видим, что удалить можно лишь каталог level_3. Что если мы хотим рекурсивно удалить каталог level_1? В этом случае зовем на помощь shutil.
Функция shutil.rmtree() сделает все, что нужно:
Пользоваться ею нужно с осторожностью, поскольку она безвозвратно удаляет все содержимое каталога.
Собственно, на этом все. 8 важных операций по работе с файлами и каталогами в среде Python мы знаем. Что касается ссылки, о которой говорилось в анонсе, то вот она — это Google Colab Network с содержимым, готовым к запуску.
Модуль Python OS используется для работы с операционной системой и является достаточно большим, что бы более конкретно описать его применение. С помощью его мы можем получать переменные окружения PATH, названия операционных систем, менять права на файлах и многое другое. В этой статье речь пойдет про работу с папками и путями, их создание, получение списка файлов и проверка на существование. Примеры приведены с Python 3, но и с предыдущими версиями ошибок быть не должно.
Модуль OS не нуждается в дополнительной установке, так как поставляется вместе с инсталлятором Python.
Навигация по посту
Получение директорий и списка файлов
Есть несколько способов вернуть список каталогов и файлов по указанному пути. Первый способ используя os.walk, который возвращает генератор:
Такие объекты можно итерировать для понятного отображения структуры:
Сам кортеж делится на 3 объекта: текущая директория, имя вложенных папок (если есть), список файлов. Я так же разделил их на примере ниже:
Os.walk является рекурсивным методом. Это значит, что для поиска файлов в конкретной директории вы будете итерировать и все вложенные папки. Обойти это с помощью самого метода нельзя, но вы можете использовать break так как os.walk возвращает указанную директорию первой. Можно так же использовать next():
Получение файлов через listdir
Есть еще один метод получения файлов используя listdir. Отличия от предыдущего метода в том, что у нас не будет разделения файлов и папок. Он так же не является рекурсивным:
Получение полного абсолютного пути к файлам
Для последующего чтения файла нам может понадобится абсолютный путь. Мы можем использовать обычный метод сложения строк или метод os.path.join, который сделает то же самое, но и снизит вероятность ошибки если программа работает на разных ОС:
Исключение каталогов или файлов из списка
У нас может быть список полных путей, например из списка выше, из которого мы хотим исключить папки или файлы. Для этого используется os.path.isfile:
Такой же принцип имеют следующие методы:
- os.path.isdir() - относится ли путь к папке;
- os.path.islink() - относится ли путь к ссылке;
Получение расширения файлов
Расширение файла можно получить с помощью os.path.splittext(). Этот метод вернет путь до расширения и само расширение. Этот метод исключает ситуацию, когда точка может стоять в самом пути. Если в качестве пути мы выберем каталог (который не имеет расширения) , результатом будет пустая строка:
os.path.basename(path) - вернет имя файла и расширение.
Создание и удаление директорий
Методы по изменению папок следующие:
- os.mkdir() - создаст папку;
- os.rename() - переименует;
- os.rmdir() - удалит.
Если попытаться создать несколько вложенных папок сразу, используя предыдущий пример, появится ошибка FileNotFoundError. Создание папок включая промежуточные выполняется с os.makedirs():
Проверка директорий и файлов на существование
Если мы пытаемся создать папку с существующим именем, то получим ошибку FileExistsError. Один из способов этого избежать - использование os.path.exists(), который вернет True в случае существования файла или папки:
Получение и изменение текущей директории
Запуская любую программу или консоль, например CMD, мы это делаем из определенной директории. С этой и соседней директорией мы можем работать без указания полного пути. Для того что бы узнать такую директорию в Python используется метод os.getcwd():
Читайте также: