如何为所有文件和关联的文件夹使用Unicode字符重命名/替换特定的关键字?

时间:2019-01-16 22:55:42

标签: python python-2.7 unicode glob python-os

我在目录('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

如何在Python 2.7中正确地重命名所有具有ABC并带有单字符的文件和文件夹?

1 个答案:

答案 0 :(得分:1)

至少有五个问题:

  1. 处理Unicode时,请在各处使用它。如果传递了Unicode路径,则os.walk将返回Unicode文件名。 from __future__ import unicode_literals将默认字符串转换为Unicode。
  2. 打开文件时,请关闭它们。重命名时会遇到问题。 result仍然存在,并且引用了最后打开的文件。
  3. 如评论中所述,在名称之前和之后的os.path.joinroot上使用file
  4. os.walktopdown=False一起使用。这将首先处理叶节点,因此遍历目录树时不会损坏它(并使rootdirs保持有效)。
  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)