2

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

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

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

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

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

5 ответов5

7

Это сообщение довольно старое, но я думаю, что могу внести свой вклад в эту проблему:
Сначала создайте скрипт с именем recodeifneeded :

#!/bin/bash
# Find the current encoding of the file
encoding=$(file -i "$2" | sed "s/.*charset=\(.*\)$/\1/")

if [ ! "$1" == "${encoding}" ]
then
# Encodings differ, we have to encode
echo "recoding from ${encoding} to $1 file : $2"
recode ${encoding}..$1 $2
fi

Вы можете использовать это так:

recodeifneeded utf-8 file.txt

Итак, если вы хотите запустить его рекурсивно и изменить все кодировки * .txt файлов на (скажем так) utf-8:

find . -name "*.txt" -exec recodeifneeded utf-8 {} \;

Надеюсь, это поможет.

3

Этот сценарий, адаптированный по идее Харримка, который условно перекодирует один файл (основываясь на существовании определенных скандинавских символов в кодировке 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. И поскольку это, очевидно, очень ограниченное решение, подходящее для того, какие файлы у меня есть, не стесняйтесь добавлять лучшие ответы, которые решают проблему в более общем виде.

2

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 для выполнения разговора, но вам понадобятся средства обнаружения UTF-8. Одним из способов является использование iconv с UTF-8 как в качестве исходной, так и целевой кодировки. Если файл был действительным UTF-8, вывод будет таким же, как и ввод.

1

Я немного опоздал, но я снова и снова сталкиваюсь с одним и тем же вопросом ... Теперь, когда я нашел отличный способ сделать это, я не могу не поделиться этим :)

Несмотря на то, что я являюсь пользователем emacs, я рекомендую вам использовать vim сегодня.

с помощью этой простой команды он перекодирует ваш файл, независимо от того, что находится внутри желаемой кодировки:

vim +'set nobomb | set fenc=utf8 | x' <filename>

никогда не находил что-то, дающее мне лучшие результаты, чем это.

Я надеюсь, что это поможет некоторым другим.

1

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .