Поиск файлов в кодировке ISO-8859-1?

У меня есть куча файлов со смесями кодировок, в основном ISO-8859-1 и UTF-8.

Я хотел бы сделать все файлы UTF-8, но при попытке пакетного кодирования этих файлов с помощью iconv возникают некоторые проблемы. (Файлы урезаются вдвое и т. Д.)

Я полагаю, причина в том, что iconv требует знать кодировку 'from', поэтому, если команда выглядит так

iconv -f ISO-8859-1 -t UTF-8 in.php -o out.php

но 'in.php', если он уже закодирован в UTF-8, вызывает проблемы (поправьте меня, если я ошибаюсь)

Есть ли способ перечислить все файлы, кодировка которых не является UTF-8?

Ответов (5)

Решение

Вы не можете найти файлы, которые определенно соответствуют ISO-8859-1, но вы можете найти файлы, которые соответствуют UTF-8 (что, в отличие от большинства многобайтовых кодировок, дает вам разумную уверенность в том, что они на самом деле являются UTF-8). У moreutils есть инструмент, isutf8 который может сделать это за вас. Или вы можете написать свой, это будет довольно просто.

с поиском это довольно просто

find . -print0 | xargs -0 file | grep 8859

Что за контент? XML? Тогда да, если правильно пометить вверху. Общие текстовые файлы? Я не знаю какого-либо априорного способа узнать, какая кодировка используется, хотя иногда это возможно с помощью умного кода. Текстовые файлы UTF-8 с тегами, под которыми я подразумеваю текстовые файлы UTF-8 с пометкой порядка байтов ? (Для UTF-8 трехбайтовая последовательность «ï» ¿») Вероятно. Символы метки порядка байтов не будут обычно появляются в качестве первых трех символов в файле, закодированном по стандарту ISO-8859-1. (Который Бобинс указал в комментарии к этому сообщению, поэтому я исправляю свой пост.)

Для ваших целей существуют инструменты, которые, вероятно, могут решить большую часть вашего вопроса. Логан Капальдо указал на одного из своем ответе .

Но ведь если бы всегда можно было однозначно выяснить, какая кодировка символов использовалась в файле, то iconv утилите не нужно было бы указывать кодировку «from». :)

Часто трудно определить, просто прочитав текстовый файл, в кодировке ли он UTF-8 или нет. Вы можете сканировать файл на предмет определенных байтов индикатора, которые никогда не встречаются в UTF-8, и если вы их найдете, вы знаете, что файл находится в ISO-8859-1. Если вы найдете байт с установленным старшим битом, где байты как непосредственно перед ним, так и сразу после него не имеют своих старших битов, вы знаете, что он закодирован в ISO (потому что байты> 127 всегда встречаются в последовательностях в UTF -8). Помимо этого, это в основном догадки - вам нужно будет посмотреть на последовательности байтов с этим старшим битом и посмотреть, имеет ли смысл их появление в ISO-8859-1 или нет.

file Программа сделает попытку угадать кодировку текстового файла , это обработка, вы можете попробовать это.

Есть ли способ перечислить все файлы, кодировка которых не является UTF-8?

Возможно, не так просто в одном только bash, но это тривиальная задача, например. Python:

import os.path

for child in os.path.listdir(TARGETDIR):
    child= os.path.join(TARGETDIR, child)
    if os.path.isfile(child):
        content= open(child, 'rb').read()

        try:
            unicode(content, 'utf-8')
        except UnicodeDecodeError:
            open(child, 'wb').write(unicode(content, 'iso-8859-1'))

Это предполагает, что любой файл, который можно интерпретировать как действительную последовательность UTF-8, является одним (и поэтому его можно оставить в покое), в то время как все, что не является, должно быть ISO-8859-1.

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