(Проблема решена, смотрите обновления)
У меня есть файлы с неправильными именами из-за проблем с кодировкой. Поэтому я хочу написать скрипт 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. Вот список моих инструментов:
- Питон: 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 и правильный китайский шрифт, поддерживающий Unicode, или проверьте следующее изображение:
К вашему сведению: имя файла в кодировке GBK не распознается моей программой загрузки и интерпретируется как строка Unicode, которая кодируется как UTF-8. Байт, отличный от ascii, в исходном файле интерпретируется как кодовая точка Unicode и кодируется с использованием UTF-8, что вызывает проблему.
Update2: скрипт, переносимый между Mac и Linux, теперь загружен здесь.
open
файла. - person Ivan Xiao   schedule 24.07.2011csh
илиsh
? - person William Niu   schedule 24.07.2011fish
,csh
,zsh
, безрезультатно. - person Ivan Xiao   schedule 25.07.2011