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

Я хочу программно изменить имена папок. На окнах он работает безупречно - на 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.