2017-01-21 4 views
0

Этот код выше переименовывает все файлы в наборе папок, чтобы они выглядели как «Файл x на x уровнях глубоко», используя его текущие данные о имени файла, но я хочу, чтобы он также переименовал папки этих файлов на «Folder x at x levels deep», но он дает ошибку, говоря, что папка уже открыта в другом процессе. Вышеприведенные комментарии - это то, что я делал до сих пор (без успеха), а остальное - в работе.Переименование папок и файлов внутри него

import os, re 

def everydirectory(path): 
    for file in os.listdir(path): 
     file_w_path = os.path.join(path, file) 
     os.chdir(path) 
     if os.path.isdir(file_w_path): 
      os.chdir(file_w_path) 
      # complete_folder_name = re.search("(deep)([0-9])(FOLDER)([0-9])", file) 
      # deepness = complete_folder_name.group(2) 
      # folder_number = complete_folder_name.group(4) 
      # new_folder_name = "Folder {} at {} levels deep".format(folder_number, deepness) 
      # new_folder_name_w_path = os.path.join(path, new_folder_name) 
      # os.rename(file_w_path, new_folder_name_w_path) 
      # print("Folder " + file_w_path + " renamed to " + new_folder_name_w_path) 
      everydirectory(file_w_path) 
     elif os.path.isfile(file_w_path): 
      path = os.path.join(path, os.getcwd()) 
      extension = os.path.splitext(file_w_path)[1] 
      complete_file_name = re.search("(deep)([0-9])(FILE)([0-9])", file) 
      deepness = complete_file_name.group(2) 
      file_number = complete_file_name.group(4) 
      new_file_name = "File {} at {} levels deep{}".format(file_number, deepness, extension) 
      new_file_name_w_path = os.path.join(path, new_file_name) 
      os.rename(file_w_path, new_file_name_w_path) 
      print("File " + file_w_path + " RENAMED TO " + new_file_name_w_path) 

directory = input("Where is the files?") 
everydirectory(directory) 

Я думаю, что проблема в том, что он переименовывает файл после программы переименовывает папку, что делает его «потерять» исходное местоположение файла. Может кто-нибудь проверить, что я делаю неправильно? Благодаря!

Вот набор папок/файлов и как я хотел, чтобы она выглядела после выполнения сценария: https://drive.google.com/drive/u/1/folders/0B8pLYoI76JJiOEtpNzdaYVZrVXM

+1

Обычный подход к такому роду переименование задачи является использование рекурсии для работы вверх от нижней части дерево каталогов. Переименуйте содержимое каталога, а затем переименуйте содержимое его родителя. –

+1

Попробуйте переименовать папку после вызова 'eachdirectory (file_w_path)' так, как это делается с любыми файлами внутри. Или, может быть, это должен быть 'everydirectory (new_folder_name_w_path)' с использованием именованного пути вместо старого пути? –

+0

@ PM2Ring Как я могу использовать рекурсию? Я попытался сделать то, что вы сказали о первом переименовании файлов с помощью функции, а затем переименовать папки, но все равно дает ту же ошибку. Я читал о os.walk (topdown = False), но не мог понять, как его использовать, вот о чем вы говорите? – Setti7

ответ

0

Я переработан код немного для того, чтобы заставить его работать. Я также следил за deep в рекурсии, но вы также можете полагаться на именах файлов, если вы предпочитаете:

import os, re 
import os.path 
from contextlib import contextmanager 

@contextmanager 
def change_dir(directory): 
    wd = os.getcwd() 
    try: 
     os.chdir(directory) 
     yield directory 
    finally: 
     os.chdir(wd) 


def rename_file(filename, deep, is_dir=False): 
    if is_dir: 
     complete_filename = re.search("(deep)([0-9])(FOLDER)([0-9])", filename) 
     file_number = complete_filename.group(4) 
     new_filename = "Folder {} at {} levels deep".format(file_number, deep) 
    else: 
     complete_filename = re.search("(deep)([0-9])(FILE)([0-9])", filename) 
     file_number = complete_filename.group(4) 
     extension = os.path.splitext(filename)[1] 
     new_filename = "File {} at {} levels deep{}".format(file_number, deep, extension) 

    os.rename(filename, new_filename) 


def every_directory(path, deep=0): 
    deep += 1 
    for file in os.listdir(path): 
     is_dir = False 
     filepath = os.path.join(path, file) 
     if os.path.isdir(filepath): 
      every_directory(filepath, deep) 
      is_dir = True 
     with change_dir(path): 
      rename_file(file, deep=deep, is_dir=is_dir) 
+0

Я начинаю программировать с помощью python и никогда не видел этого «@contextmanager», что он делает? – Setti7

+1

«contextmanager» - это просто удобный декоратор, который можно использовать для определения функции, которая может использоваться с 'with'-statement без необходимости создания класса или отдельных методов __enter __() и __exit __(). Посмотрите на декораторы, оператор with на python, если вы хотите узнать больше. Когда вы поймете эти две вещи, вы можете посмотреть документацию для contextlib: https://docs.python.org/3.4/library/contextlib.html –

+0

Спасибо! Я уже почти решил свою проблему без использования декораторов (пока не узнал о них). Но теперь я застрял: мой «исправленный» новый скрипт не меняет имена файлов первой папки (основной папки, а не deep1FOLDER1), и я не знаю почему. Не могли бы вы его увидеть? Подробнее в этой [link] (https://drive.google.com/drive/u/0/folders/0B8pLYoI76JJT2I5YTVXb2t6RjQ) – Setti7

Смежные вопросы