Как узнать языковую кодировку имени файла в Linux?

17

У меня есть каталог с ~ 10000 файлов изображений из внешнего источника.

Многие из имен файлов содержат пробелы и знаки препинания, которые не подходят для БД или для Интернета. Я также хочу добавить номер SKU в конце каждого имени файла (для целей бухгалтерского учета). Многие, если не большинство имен файлов также содержат расширенные латинские символы, которые я хочу сохранить для целей SEO (в частности, чтобы имена файлов точно представляли содержимое файла в Google Images)

Я сделал bash-скрипт, который переименовывает (копирует) все файлы до желаемого результата. Скрипт bash сохраняется в UTF-8. После запуска он пропускает около 500 файлов (не в состоянии stat файл ...).

Я запустил в каталоге convmv -f UTF-8 -t UTF-8 и обнаружил, что эти 500 имен файлов не кодируются в UTF-8 (convmv способен обнаруживать и игнорировать имена файлов, уже существующие в UTF-8)

Есть ли простой способ узнать, какую кодировку языка они используют в настоящее время?

Единственный способ, которым я смог сам разобраться, это установить для моего терминального кодирования UTF-8, а затем перебирать все возможные кодировки кандидатов с помощью convmv, пока он не отобразит преобразованное имя, которое «выглядит правильно». У меня нет возможности быть уверенным, что все эти 500 файлов используют одну и ту же кодировку, поэтому мне придется повторить этот процесс 500 раз. Я хотел бы более автоматизированный метод, чем «выглядит правильно» !!!

rwired
источник

Ответы:

13

Там нет 100% точного способа на самом деле, но есть способ дать хорошее предположение.

Существует кодекс библиотеки Python, который доступен здесь: https://pypi.python.org/pypi/chardet

например

Посмотрите, что для текущей переменной LANG установлено:

$ echo $LANG
en_IE.UTF-8

Создайте имя файла, которое должно быть закодировано с помощью UTF-8

$ touch mÉ.txt

Измените нашу кодировку и посмотрите, что произойдет, когда мы попытаемся перечислить ее

$ ls m*
mÉ.txt
$ export LANG=C
$ ls m*
m??.txt

Хорошо, теперь у нас есть имя файла, закодированное в UTF-8, и наша текущая локаль - C (стандартная кодовая страница Unix).

Итак, запустите python, импортируйте chardet и заставьте его прочитать имя файла. Я использую некоторые оболочки (например, расширение через символ *), чтобы получить мой файл. Измените "ls m *" на любой, который будет соответствовать одному из ваших файлов примеров.

>>> import chardet
>>> import os
>>> chardet.detect(os.popen("ls m*").read())
{'confidence': 0.505, 'encoding': 'utf-8'}

Как видите, это только предположение. Насколько хорошо предположение показывает переменная «достоверность».

Филип Рейнольдс
источник
скрипт работает, как описано, но в моем случае chardet не нашел кодировку файла.
Федир Рыхтик
6

Это может оказаться полезным для проверки текущего рабочего каталога (python 2.7):

import chardet
import os  

for n in os.listdir('.'):
    print '%s => %s (%s)' % (n, chardet.detect(n)['encoding'], chardet.detect(n)['confidence'])

Результат выглядит так:

Vorlagen => ascii (1.0)
examples.desktop => ascii (1.0)
Öffentlich => ISO-8859-2 (0.755682154041)
Videos => ascii (1.0)
.bash_history => ascii (1.0)
Arbeitsfläche => EUC-KR (0.99)

Чтобы извлечь путь из текущего каталога, скопируйте и вставьте его в небольшой скрипт на python:

#!/usr/bin/python

import chardet
import os

for root, dirs, names in os.walk('.'):
    print root
    for n in names:
        print '%s => %s (%s)' % (n, chardet.detect(n)['encoding'], chardet.detect(n)['confidence'])
Клаус Каппель
источник
Это работает и с азиатской кодировкой? Или это евроцентрик?
перепечатано