2010-06-10 2 views
4

У меня есть куча музыкальных файлов на разделе NTFS, смонтированном на Linux, которые имеют имена файлов с символами Unicode. У меня возникли проблемы с написанием сценария для переименования файлов, чтобы все имена файлов использовали только символы ASCII. Я думаю, что использование команды iconv должно работать, но у меня возникли проблемы с экранированием символов для команды 'mv'.Как преобразовать имена файлов из unicode в ascii

EDIT: Не имеет значения, нет ли прямой транслирации для символов юникода. Я предполагаю, что я просто заменил их на «?» персонаж.

+0

Язык? Если это bash, поместите его в кавычки? Если это какой-то другой язык, не вызывайте mv, вызывайте правильный syscall? – Thanatos

+0

Кроме того, что мы делаем, если найдем символ Unicode?火 не имеет эквивалента ASCII. – Thanatos

ответ

2

Я не думаю, что у iconv есть какие-либо средства для замены символов. Это в Python может помочь:

#!/usr/bin/python 
import sys 

def unistrip(s): 
    if isinstance(s, str): 
     s = s.decode('utf-8') 
    chars = [] 
    for i in s: 
     if ord(i) > 0x7f: 
      chars.append(u'?') 
     else: 
      chars.append(i) 
    return u''.join(chars) 

if __name__ == '__main__': 
    print unistrip(sys.argv[1]) 

Тогда зови как:

$ ./unistrip.py "yikes__oh_look_a_file_火" 
yikes_?_oh_look_a_file_? 

также:

$ mv "yikes__oh_look_a_file_火" "`./unistrip.py "yikes__oh_look_a_file_火"`" 

Вы можете проверить это немного первый. Для больших операций перемещения рекомендуется создать список команд mv (то есть написать код для написания сценария), так как вы можете просмотреть команды перемещения перед тем, как сообщить им выполнить.

+1

'return s.encode ('ascii', 'replace')' –

+0

Исправьте меня, если я ошибаюсь, но я думаю, что 'iconv' имеет возможности замены символов: http://stackoverflow.com/questions/1975057/ Баш-новообращенный-не-ASCII-символы к ASCII –

2

convmv - хороший сценарий Perl для преобразования кодировок имен файлов. Но он не может обрабатывать символы, которые не находятся в кодировке назначения.

Вы можете изменить любой символ не в ASCII на '?' используя утилиту переименования, распространяемую вместе с Perl:

rename 's/[^ -~]/?/g' * 

К сожалению, это заменяет многобайтовые символы несколькими? В зависимости от кодировки Unicode, которая используется, и символы, связанные с изменением регулярного выражения, могут помочь, например.

rename 's/[^ -~]{2}/?/g' * 

для двухбайтовых символов.

3

Иногда mv не сможет прочитать имя файла в оболочке, поэтому вы можете попробовать ссылку inode.

Чтобы получить инод файла:

$ ls -il

выхода будет что-то вроде этого:

13377799 -rw-r--r-- 1 draco draco  11809 Apr 25 01:39 some_filename.ext 
9340462 -rw-r--r-- 1 draco draco  81648 Apr 23 02:27 some_strange_filename.ext 
9340480 -rw-r--r-- 1 draco draco  4717 Apr 23 03:54 yikes__oh_look_a_file_火 

Затем используйте find, чтобы получить файл и, возможно, используя код питона по Танатосу :

$ find . -inum 9340480 -exec ./unistrip.py {} \;

Вы также можете использовать приведенную выше команду с iconv в оболочке.

Надеюсь, что это поможет кому-то, и извините меня за любые ошибки [первый ответ].

Смежные вопросы