(проблема решена, пожалуйста, смотрите обновления)
У меня есть несколько файлов с неправильными именами файлов из-за проблем с кодировкой. Поэтому я хочу написать скрипт Python для его обработки. Однако я сталкиваюсь со странной проблемой.
Чтобы лучше проиллюстрировать, я буду использовать пример: имя файла отображается как ¹þÀï·ÑÇ.mp3
.
Однако следующий результат отличается:
# only one mp3 file is in this directory:
$ ls *mp3 | hexdump
0000000 c2 b9 c3 be 41 cc 80 69 cc 88 41 cc 82 c2 b7 4e
0000010 cc 83 43 cc a7 2e 6d 70 33 0a
000001a
$ echo "¹þÀï·??Ç.mp3" | hexdump
0000000 c2 b9 c3 be c3 80 c3 af c3 82 c2 b7 c3 91 c3 87
0000010 2e 6d 70 33 0a
0000015
По сути, вторая строка (или байты) - это та, которую я хотел, но в моем скрипте Python аргументы командной строки всегда дают мне первую строку. У меня нет возможности обойти.
Я заметил, что это происходит только в Mac OS X. Следовательно, я подозреваю, что аргумент каким-то образом закодирован или обработан в bash / system / python.
Вот список моих инструментов:
- Python: 2.7.2
- ОС: Mac OS X 10.6.7
- Оболочка:
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)
Обновление: следующий код хорошо работает в моем Arch Linux , но страдает от вышеуказанной проблемы в моем Mac OS X:
#!/usr/bin/env python
import sys
import os
for name in sys.argv[1:]:
try:
# This line does the magic:
new_name = name.decode('utf8').encode('latin-1').decode('gbk')
new_name_utf8 = new_name.encode('utf8')
if name != new_name_utf8:
print "%s -> %s" % (name, new_name_utf8)
os.rename(name, new_name)
except:
print "Ignoring %s" % name
В оболочке запустите:
$ ./the_script *mp3 # Let bash pass the file name string
Вы можете запустить приведенный выше код для строки ¹þÀï·ÑÇ.mp3
, и он должен быть правильно обозначен как 哈里路亚.mp3
. Обратите внимание, что у вас должен быть языковой стандарт UTF-8 и правильный китайский шрифт, поддерживающий Юникод, для правильного отображения, или проверьте следующее изображение:
К вашему сведению: имя файла в кодировке GBK не распознается моей программой загрузки, и оно интерпретируется как строка в кодировке Unicode, которая кодируется как UTF-8. Байт, отличный от ascii, в исходном файле интерпретируется как кодовая точка Unicode и кодируется с использованием UTF-8, что вызывает проблему.
Update2: скрипт, переносимый между Mac и Linux, теперь загружен здесь .