Gedit не может распознать кодировку символов, но Gvim может

У меня есть много текстовых файлов, которые приходят из среды Windows.
Многие из них используют странную кодовую страницу Windows по умолчанию, которая не является ни ASCII (7 бит), ни UTF-8.

У gvim нет проблем с открытием этих файлов, но gedit не может этого сделать.
gvim сообщает кодировку как latin1.

Я предполагаю, что gvim делает "умное" предположение о кодовой странице.
(Я считаю, что эта кодовая страница все еще имеет международные варианты).

Некоторые вопросы возникают из этого:

  • (1). Есть ли какой-нибудь способ, которым gedit можно сказать, чтобы распознать эту кодовую страницу?
    ** NB. [Обновление] Для этого пункта (1), см. Мой ответ ниже.
    ** Для пунктов (2) и (3). увидеть ответ Оли.

  • (2). Есть ли способ сканирования файловой системы для выявления этих проблемных файлов?

  • (3). Существует ли инструмент пакетного преобразования для преобразования этих файлов в UTF-8?

(... этот текстовый хаос старого мира на самом деле был последней каплей, которая привела меня в Ubuntu... UTF-8 по умолчанию для всей системы Brilliant)

[ОБНОВИТЬ]
** NB: ** Теперь я считаю, что следующее обновление частично бесполезно, потому что "проблемные" файлы не являются "проблемными" (см. Мой ответ ниже).
Я оставил это здесь, потому что это может быть полезным для кого-то.


Я разработал грубый и готовый способ определения проблемных файлов...
file команда не подходит, потому что она определила мой файл примера как ASCII... но файл ASCII на 100% соответствует UTF-8...

Как я упоминал в комментарии ниже, тест на недопустимый первый байт кодовой точки UTF-8:

  • если первый байт (из кодовой точки UTF-8) находится между 0x80 и 0xBF (зарезервирован для дополнительных байтов) или больше 0xF7 ("чрезмерно длинная форма"), это считается ошибкой

я знаю sed (немного, через порт Win32), поэтому мне удалось собрать воедино шаблон RegEx, который находит эти ошибочные байты.

Это уродливая строка, поэтому отведите взгляд, если регулярные выражения вас пугают:)

Я был бы очень признателен, если бы кто-то указал, как использовать шестнадцатеричные значения в выражении range []. Я только что использовал оператор or \ |

fqfn="/my/fully/qualified/filename"  
sed -n "/\x80\|\x81\|\x82\|\x83\|\x84\|\x85\|\x86\|\x87\|\x88\|\x89\|\x8A\|\x8B\|\x8C\|\x8D\|\x8E\|\x8F\|\x90\|\x91\|\x92\|\x93\|\x94\|\x95\|\x96\|\x97\|\x98\|\x99\|\x9A\|\x9B\|\x9C\|\x9D\|\x9E\|\x9F\|\xA0\|\xA1\|\xA2\|\xA3\|\xA4\|\xA5\|\xA6\|\xA7\|\xA8\|\xA9\|\xAA\|\xAB\|\xAC\|\xAD\|\xAE\|\xAF\|\xB0\|\xB1\|\xB2\|\xB3\|\xB4\|\xB5\|\xB6\|\xB7\|\xB8\|\xB9\|\xBA\|\xBB\|\xBC\|\xBD\|\xBE\|\xBF\|\xF8\|\xF9\|\xFA\|\xFB\|\xFC\|\xFD\|\xFE\|\xFF/p" "${fqfn}"  

Итак, я сейчас привью это в пакетное решение Оли... Спасибо Оли!

PS. Вот недопустимый байт UTF-8, найденный в моем образце файла...
"H.Bork, Gøte-borg."... "ø" = F8 hex... который является недопустимым символом UTF-8.

4 ответа

Решение

iconv это, вероятно, то, что вы хотите использовать. iconv -l покажет вам доступные кодировки, а затем вы можете использовать пару команд для их перекодирования:

# all text files are in ./originals/
# new files will be written to ./newversions/

mkdir -p newversions
cd originals
for file in *.txt; do
    cat $file | iconv -f ASCII -t utf-8 > ../newversions/$file;
done

Если вы хотите сделать это с файлами, кодирование которых вы не используете (потому что они повсюду), вам нужно ввести еще несколько команд: find, file, awk а также sed, Последние два просто для обработки вывода файла.

for file in find . -type f -exec file --mime {} \; | grep "ascii" | awk '{print $1}' | sed s/.$//; do
    ...

Я понятия не имею, работает ли это на самом деле, поэтому я, конечно, не запустил бы его из ничего, кроме наименее важного каталога, который у вас есть (создайте папку для тестирования с некоторыми известными файлами ASCII). Синтаксис find может помешать ему находиться внутри цикла for. Я надеюсь, что кто-то другой с большим опытом работы с bash может подключиться и разобраться, чтобы он делал правильные вещи.

Gedit может определить правильный набор символов, только если он указан в "File-Open-Character Encoding". Вы можете изменить этот список, но имейте в виду, что порядок важен.

Вы можете использовать любую из 3 командных строк:

gedit --encoding=utf-8 filename
gedit --encoding=iso-8859-15 filename
gedit --encoding=utf-16 filename
. . . . .

Я думал об этом немного больше...

Да, "ø" = 0xF8 hex* определенно было причиной, по которой gedit не открывал файл...
Зачем? Потому что это не правильный байт UTF-8.
По умолчанию gedit открывает только файлы UTF-8...

Однако в gedit есть функция автоопределения кодовой страницы, но вы должны сначала добавить кодовые страницы в список "возможных".

Ярко-красный диалог, который появляется, когда gedit не может распознать кодовую страницу, содержит кнопку, которая позволяет вам добавить другую кодовую страницу...

Проблема решена!... почти...

Теперь этот вопрос снова поднимает голову... Какая это кодовая страница?

В моей ситуации я могу разумно предположить, что это стандартная английская кодовая страница Windows (для моего региона? Или для региона происхождения файла? .. Я упомянул "knarly":)....

В любом случае, gedit позволит вам загрузить файл, как только вы добавите кодовую страницу в его список...

Таким образом, хотя все команды терминала являются полезными и интересными сами по себе, кажется, что эта точка зрения движется в неверном направлении.

В этих файлах нет ничего неправильного...
Проблема, похоже, касается исключительно кодовых страниц.

Gedit может открыть файл так же, как и Gvim.
... но соответствующая кодовая страница должна быть сначала добавлена в список кодовых страниц.
например. через диалог открытия файла или красный диалог предупреждения, с которым я столкнулся.

Другие вопросы по тегам