Как повторно кодировать к UTF-8 условно?

Я объединяю кодирование большого набора текстовых файлов, собираемых со временем на различных компьютерах. Я главным образом иду от ISO-8859-1 до UTF-8. Это приятно преобразовывает один файл:

recode ISO-8859-1..UTF-8 file.txt

Я, конечно, хочу сделать автоматизированную пакетную обработку для всех файлов, и просто рабочее вышеупомянутое для каждого файла имеет проблему, что файлам, чей уже закодированный в UTF-8, повредят их кодирование. (Например, символ 'ä' первоначально в ISO-8859-1 появится как это, просматриваемое как UTF-8, если вышеупомянутый перекод будет сделан дважды: � -> ä -> ä)

Мой вопрос, какой запущенный скрипт повторно кодировал бы, только если необходимый, т.е. только для файлов, которые уже не были в целевом кодировании (UTF-8 в моем случае)?

От рассмотрения страницы справочника перекода я не мог выяснить, как сделать что-то вроде этого. Таким образом, я предполагаю, что это сводится к тому, как легко проверить кодирование файла, или по крайней мере если это - UTF-8 или нет. Этот ответ подразумевает, что Вы могли распознать допустимые файлы UTF-8 с перекодом, но как? Любой другой инструмент был бы прекрасен также, пока я мог использовать результат в условном выражении в сценарии удара...

3
задан 20.03.2017, 12:17

3 ответа

Этот сценарий, адаптированный от идеи harrymc, которая повторно кодирует один файл условно (на основе существования определенного UTF-8 закодировал скандинавские символы), кажется, работает на меня более-менее сносно.

$ cat recode-to-utf8.sh 

#!/bin/sh
# Recodes specified file to UTF-8, except if it seems to be UTF-8 already

result=`grep -c [åäöÅÄÖ] $1` 
if [ "$result" -eq "0" ]
then
    echo "Recoding $1 from ISO-8859-1 to UTF-8"
    recode ISO-8859-1..UTF-8 $1 # overwrites file
else
    echo "$1 was already UTF-8 (probably); skipping it"
fi

(Файлы пакетной обработки являются, конечно, простым вопросом, например. for f in *txt; do recode-to-utf8.sh $f; done.)

NB: это полностью зависит от самого файла сценария, являющегося UTF-8. И поскольку это - очевидно, очень ограниченное решение, подходящее, какие файлы я, оказывается, имею, не стесняйтесь добавлять лучшие ответы, которые решают проблему более универсальным способом.

3
ответ дан 07.12.2019, 22:52

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

Если количество забавных символов не является чрезмерным, Вы могли бы использовать egrep, чтобы просканировать и узнать, каким файлам нужно перекодирование.

1
ответ дан 07.12.2019, 22:52

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

Таким образом, можно сделать что-то вроде этого (в Python):

def convert_to_utf8(data):
    try:
        data.decode('UTF-8')
        return data  # was already UTF-8
    except UnicodeError:
        return data.decode('ISO-8859-1').encode('UTF-8')

В сценарии оболочки можно использовать iconv для выполнения converstion но Вам будет нужно средство обнаружения UTF-8. Один путь состоит в том, чтобы использовать iconv с UTF-8 и как источник и как целевая кодировка. Если файл был допустимым UTF-8, вывод совпадет с входом.

2
ответ дан 07.12.2019, 22:52

Теги

Похожие вопросы