У меня есть фон C ++ / Obj-C, и я только открываю Python (пишу его около часа). Я пишу скрипт для рекурсивного чтения содержимого текстовых файлов в структуре папок.
Проблема, которую я имею, состоит в том, что написанный мной код будет работать только для одной папки. Я могу понять, почему в коде (см. #hardcoded path
) Я просто не знаю, как мне двигаться дальше с Python, поскольку мой опыт работы с ним только новый.
Код Python:
import os
import sys
rootdir = sys.argv[1]
for root, subFolders, files in os.walk(rootdir):
for folder in subFolders:
outfileName = rootdir + "/" + folder + "/py-outfile.txt" # hardcoded path
folderOut = open( outfileName, 'w' )
print "outfileName is " + outfileName
for file in files:
filePath = rootdir + '/' + file
f = open( filePath, 'r' )
toWrite = f.read()
print "Writing '" + toWrite + "' to" + filePath
folderOut.write( toWrite )
f.close()
folderOut.close()
os.walk
это неплохо, хотя я придумал еще более быстрый путьos.scandir
. Всеglob
решения намного медленнее, чемwalk
&scandir
. Мою функцию, а также полный анализ скорости можно найти здесь: stackoverflow.com/a/59803793/2441026Если вы используете Python 3.5 или выше, вы можете сделать это в 1 строку.
Как указано в документации
Если вы хотите каждый файл, вы можете использовать
источник
root_dir
требует косой черты? Это сэкономит людям время (или, по крайней мере, сэкономит мне время). Спасибо.glob.iglob(root_dir + '**/**', recursive=True)
. Я работаю в Python 3.8.2Согласитесь с Дейвом Уэббом,
os.walk
выдаст элемент для каждого каталога в дереве. Факт в том, что тебе просто не нужно заботитьсяsubFolders
.Код, подобный этому, должен работать:
источник
TL; DR: это эквивалентно просмотру
find -type f
всех файлов во всех папках ниже, включая текущую:Как уже упоминалось в других ответах,
os.walk()
это ответ, но это можно объяснить лучше. Это довольно просто! Давайте пройдемся по этому дереву:С этим кодом:
Это
currentpath
текущая папка, на которую она смотрит. Это выведет:Таким образом, он зацикливается три раза, потому что есть три папки: текущая
docs
, иpics
. В каждом цикле он заполняет переменныеfolders
иfiles
всеми папками и файлами. Давайте покажем им:Это показывает нам:
Таким образом , в первой строке, мы видим , что мы находимся в папке
.
, что она содержит две папки , а именноpics
иdocs
, и что есть один файл, а именноtodo.txt
. Вам не нужно ничего делать, чтобы вернуться в эти папки, потому что, как вы видите, он повторяется автоматически и просто дает вам файлы в любых подпапках. И любые подпапки этого (хотя у нас их нет в примере).Если вы просто хотите просмотреть все файлы, что эквивалентно
find -type f
, вы можете сделать это:Это выводит:
источник
pathlib
Библиотека действительно отлично подходит для работы с файлами. Вы можете сделать рекурсивный шар наPath
объекте, как это.источник
Если вам нужен плоский список всех путей под данным каталогом (как
find .
в оболочке):Чтобы включить только полные пути к файлам в базовом каталоге, не указывайте
+ subdirs
.источник
**/**
используется , чтобы получить все файлы рекурсивно , включаяdirectory
.if os.path.isfile(filename)
используется, чтобы проверить, является лиfilename
переменнаяfile
илиdirectory
, если это файл, то мы можем прочитать этот файл. Здесь я печатаю файл.источник
Я нашел следующее, чтобы быть самым простым
Использование
glob('some/path/**', recursive=True)
получает все файлы, но также включает в себя имена каталогов. Добавлениеif os.path.isfile(f)
условия фильтрует этот список только к существующим файламисточник
использовать
os.path.join()
для построения ваших путей - это аккуратнее:источник
os.walk
делает рекурсивную прогулку по умолчанию. Для каждого каталога, начиная с корня, получается 3-х кортеж (dirpath, dirnames, filenames)источник
walk()
делать вернуться рекурсивный список. Я попробовал ваш код и получил список с множеством повторов ... Если вы просто удалите строки под комментарием "# рекурсивные вызовы для подпапок" - все работает отличноПопробуй это:
источник
Я думаю, проблема в том, что вы
os.walk
неправильно обрабатываете вывод .Во-первых, измените:
чтобы:
rootdir
Ваш фиксированный начальный каталог;root
это каталог , возвращаемыйos.walk
.Во-вторых, вам не нужно делать отступ для цикла обработки файлов, так как нет смысла запускать его для каждого подкаталога. Вы получите
root
настройки для каждого подкаталога. Вам не нужно обрабатывать подкаталоги вручную, если вы не хотите что-то делать с самими каталогами.источник
filePath = rootdir + '/' + file
, это звучит неправильно: файл находится в списке текущих файлов, значит, вы пишете во множество существующих файлов?