Как правильно переименовать папку?

Я хочу программно изменить имена папок. На окнах он работает безупречно - на linux он разбит A?A¶A¼ (Äöü). Locales on unix отлично работает - используя en_US.UTF-8 Когда я создаю каталог (называемый Äöü) на том же пути, что и мой скрипт, он корректно отображается как Äöü. Когда Python генерирует каталог, он отображается как A?A¶A¼.

вход

Äöü

Фактический результат

A?A¶A¼

Ожидаемый результат

Aeoeue

У меня есть набор символов, которые нужно заменить.

ä : ae 
Ä : Ae
ö : oe
Ö : Oe
ü : ue
Ü : Ue
á : a
à : a
Á : A
....

Вот как я читаю файл:

def __getChars(file):
 chars = {}
 with open(file) as f:
 content = f.readlines()
 for c in content:
 c = c.split(':')
 x = c[0].strip()

 try:
 y = c[1].strip()
 except:
 y = ''
 chars[x] = y
 return chars

Вот как я заменяю имена

def __replace(string):
 try:
 string = string.encode('utf8')
 except:
 pass
 for char in chars.keys():
 key = char
 value = chars[key]
 string = string.replace(key, value)
 return string

Вот как я называю __replace()

chars = __getChars(os.path.join(os.getcwd(), 'system', 'replace'))

for path in os.listdir(root):
 src = os.path.join(root, path)
 if os.path.isdir(src):
 dst = os.path.join(root, __replace(repr(path).decode('unicode-escape')))
 if src != dst:
 os.rename(src, dst)
1 ответ

Проблема заключалась в этом взломе:

repr(path).decode('unicode-escape')

Вы не можете быть уверены в кодировании байт-кода в разных системах, даже в Windows с различными системными кодировками или иначе скомпилированным Python, например CygWin или PyWin. Единственный верный метод - получить список имен файлов в listdir вызвав listdir с помощью пути unicode, например os.listdir(u'.') Или os.listdir(root.decode('utf-8')): Гораздо лучше делать все операции с файловой системой в юникоде.

Я даже написал аналогичную простую программу, которая работает как на Python 2, так и на Python 3 без каких-либо взломов, и она может переименовать все файлы и каталоги в дереве в ASCII. Большинство ваших замещений, которые удаляют только буквы из букв, можно сделать

from unicodedata import normalize
out_str = normalize('NFKD', in_str).encode('ascii', 'ignore').decode('ascii')

licensed under cc by-sa 3.0 with attribution.