Я объединяю кодирование большого набора текстовых файлов, собираемых со временем на различных компьютерах. Я главным образом иду от 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 с перекодом, но как? Любой другой инструмент был бы прекрасен также, пока я мог использовать результат в условном выражении в сценарии удара...
Этот сценарий, адаптированный от идеи 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. И поскольку это - очевидно, очень ограниченное решение, подходящее, какие файлы я, оказывается, имею, не стесняйтесь добавлять лучшие ответы, которые решают проблему более универсальным способом.
И ISO-8859-1 и UTF-8 идентичны на первых 128 символах, таким образом, Ваша проблема состоит действительно в том, как обнаружить файлы, которые содержат забавные символы, означая численно закодированный как выше 128.
Если количество забавных символов не является чрезмерным, Вы могли бы использовать egrep, чтобы просканировать и узнать, каким файлам нужно перекодирование.
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, вывод совпадет с входом.