Как переименовать / заменить определенное ключевое слово символом Юникод для всех файлов и связанных папок? - PullRequest
0 голосов
/ 17 января 2019

У меня есть следующие файлы и подкаталоги в каталоге ('input_folder'), и я хотел бы изменить имя всех файлов с расширением '.dat' и всех папок с определенным ключевым словом (например, ABC) ) с символом Unicode. MWE дано ниже:

import os
import random
import errno    
#--------------------------------------
# Create random folders and files

# tzot's forced directory create hack https://stackoverflow.com/a/600612/4576447
def mkdir_p(path):
    try:
        os.makedirs(path)
    except OSError as exc:  # Python >2.5
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else:
            raise


if not os.path.isdir('./input_folder'):
    os.makedirs('input_folder')
for i in range(10):
    mkdir_p('./input_folder/folder_ABC_' + str(random.randint(100,999)))


for root, dirs, files in os.walk('./input_folder'):
    for dir in dirs:
        result = open(os.path.join(root,dir) + '/ABC ' + str(random.randint(100,999)) + '.dat','w')
        result = open(os.path.join(root,dir) + '/XYZ-ABC ' + str(random.randint(100,999)) + '.dat','w')

#--------------------------------------
# Main rename code

for root, dirs, files in os.walk('./input_folder'):
    for file in files:  
        if file.endswith((".dat")):
            os.rename(file, file.replace('ABC', u'\u2714'.encode('utf-8')))

Это MWE выдает следующую ошибку:

os.rename(file, file.replace('ABC', u'\u2714'.encode('utf-8')))
WindowsError: [Error 2] The system cannot find the file specified

Как правильно переименовать все файлы и папки, в которых есть ABC, с символом unioode в Python 2.7?

1 Ответ

0 голосов
/ 17 января 2019

Существует как минимум пять выпусков:

  1. При работе с Юникодом используйте его везде. os.walk вернет имена файлов Unicode, если передан путь Unicode. from __future__ import unicode_literals по умолчанию будет использовать Unicode.
  2. При открытии файлов закройте их. Вы столкнетесь с проблемами позже при переименовании. result все еще существует и имеет ссылку на последний открытый файл.
  3. Как уже упоминалось в комментарии, используйте os.path.join для root и file для имени до и после.
  4. Используйте os.walk с topdown=False. Сначала будут обработаны конечные узлы, поэтому дерево каталогов не будет повреждено (и сохранится действительным root и dirs) при его обходе.
  5. Сначала переименуйте файлы, затем каталоги, чтобы не повредить дерево каталогов при его обходе.

Результат:

from __future__ import unicode_literals

# Skipping unchanged code...

for root, dirs, files in os.walk('./input_folder'):
    for dir in dirs:
        # One way to ensure the file is closed.
        with open(os.path.join(root,dir) + '/ABC ' + str(random.randint(100,999)) + '.dat','w'):
            pass
        with open(os.path.join(root,dir) + '/XYZ-ABC ' + str(random.randint(100,999)) + '.dat','w'):
            pass

#--------------------------------------
# Main rename code

for root, dirs, files in os.walk('./input_folder',topdown=False):
    for file in files:  
        if file.endswith((".dat")):
            # Generate the full file path names.
            filename1 = os.path.join(root,file)
            filename2 = os.path.join(root,file.replace('ABC', '\u2714'))
            os.rename(filename1,filename2)
    for d in dirs:  
        # Generate the full directory path names.
        dirname1 = os.path.join(root,d)
        dirname2 = os.path.join(root,d.replace('ABC', '\u2714'))
        os.rename(dirname1,dirname2)
...