Кодировка от Windows 1252 до UTF-8 - PullRequest
       38

Кодировка от Windows 1252 до UTF-8

33 голосов
/ 06 января 2010

Я скопировал определенные файлы с машины Windows на машину Linux. Поэтому все файлы в кодировке Windows (windows-1252) необходимо преобразовать в UTF-8. Файлы, которые уже находятся в UTF-8, не должны быть изменены. Я планирую использовать для этого утилиту recode. Как я могу указать, что утилита recode должна преобразовывать только файлы в кодировке Windows-1252, а не файлы UTF-8?

Пример использования перекодировки:

recode windows-1252.. myfile.txt

Это конвертирует myfile.txt из windows-1252 в UTF-8. Прежде чем сделать это, я хотел бы знать, что myfile.txt на самом деле кодируется в windows-1252, а не в кодировке UTF-8. В противном случае, я считаю, что это повредит файл.

Ответы [ 10 ]

63 голосов
/ 06 января 2010

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

iconv -f WINDOWS-1252 -t UTF-8 filename.txt

37 голосов
/ 06 января 2010

Как вы ожидаете, что код перекодировки узнает, что это файл Windows-1252? Теоретически, я считаю, что любой файл является допустимым файлом Windows-1252, поскольку он сопоставляет каждый возможный байт с символом.

Теперь, безусловно, есть характеристики, которые настоятельно подсказывают , что это UTF-8 - если он начинается, например, с спецификации UTF-8 - но они не будут окончательными.

Один из вариантов - определить, действительно ли это первый файл UTF-8, сначала, я полагаю ... опять-таки, это только наводит на мысль.

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

В качестве альтернативы, делайте это программно, а не с помощью утилиты перекодирования - это было бы довольно просто, например, в C #.

Просто повторюсь: все это эвристично. Если вы действительно не знаете кодировку файла, ничто не скажет вам это со 100% точностью.

9 голосов
/ 20 сентября 2012

Вот транскрипция другого ответа, который я дал на аналогичный вопрос:

Если вы примените utf8_encode () к уже строке UTF8, она вернет искаженный вывод UTF8.

Я сделал функцию, которая решает все эти проблемы. Он называется Encoding :: toUTF8 ().

Вам не нужно знать, какова кодировка ваших строк. Это может быть Latin1 (iso 8859-1), Windows-1252 или UTF8, или в строке может быть их сочетание. Encoding :: toUTF8 () преобразует все в UTF8.

Я сделал это, потому что служба давала мне все данные, перепутанные, смешивая UTF8 и Latin1 в одной строке.

Использование:

$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);

$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);

Скачать:

https://github.com/neitanod/forceutf8

Обновление:

Я включил еще одну функцию, Encoding :: fixUFT8 (), которая будет исправлять каждую строку UTF8, которая выглядит искаженной.

Использование:

$utf8_string = Encoding::fixUTF8($garbled_utf8_string);

Примеры:

echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");

выведет:

Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football

Обновление: я преобразовал функцию (forceUTF8) в семейство статических функций в классе под названием Encoding. Новая функция - Encoding :: toUTF8 ().

8 голосов
/ 06 января 2010

Нет общего способа определить, закодирован ли файл с определенной кодировкой. Помните, что кодировка - это не что иное, как «соглашение» о том, как биты в файле должны отображаться в символы.

Если вы не знаете, какие из ваших файлов на самом деле уже закодированы в UTF-8, а какие - в windows-1252, вам придется проверить все файлы и выяснить это самостоятельно. В худшем случае это может означать, что вы должны открыть каждый из них с помощью любой из двух кодировок и посмотреть, правильно ли они выглядят - то есть все символы отображаются правильно. Конечно, вы можете использовать инструментальную поддержку для того, чтобы сделать это, например, если вы точно знаете, что определенные символы содержатся в файлах, которые имеют различное отображение в windows-1252 и UTF-8, вы можете использовать grep для них после запуска файлов через 'iconv', как упомянул Сева Акксеев.

Еще одним удачным случаем для вас будет, если вы знаете, что файлы на самом деле содержат только символы, которые одинаково закодированы как в UTF-8, так и в windows-1252. В этом случае, конечно, вы уже сделали.

6 голосов
/ 19 января 2016

Если вы хотите переименовать несколько файлов в одной команде - скажем, вы хотите преобразовать все *.txt файлы - вот команда:

find . -name "*.txt" -exec iconv -f WINDOWS-1252 -t UTF-8 {} -o {}.ren \; -a -exec mv {}.ren {} \;
2 голосов
/ 06 января 2010

Используйте команду iconv .

Чтобы убедиться, что файл находится в Windows-1252, откройте его в блокноте (в Windows) и нажмите «Сохранить как». Блокнот предлагает текущую кодировку по умолчанию; если это Windows-1252 (или любая 1-байтная кодовая страница, в этом отношении), то будет написано «ANSI».

1 голос
/ 27 марта 2013

Вы можете изменить кодировку файла с помощью редактора, такого как notepad ++. Просто зайдите в Encoding и выберите то, что вы хотите.

Я всегда предпочитаю Windows 1252

0 голосов
/ 30 мая 2016

UTF-8 не имеет спецификации, поскольку она является излишней и недействительной. Где полезна спецификация - в UTF-16, который может быть заменен байтами, как в случае Microsoft. UTF-16 если для внутреннего представления в буфере памяти. Используйте UTF-8 для обмена. По умолчанию и UTF-8, и все остальное, полученное из US-ASCII и UTF-16, имеют естественный / сетевой порядок байтов. Для Microsoft UTF-16 требуется спецификация, так как она поменялась байтами.

Чтобы преобразовать Windows-1252 в ISO8859-15, я сначала конвертирую ISO8859-1 в US-ASCII для кодов с похожими символами. Затем я преобразую Windows-1252 в ISO8859-15, другие символы, отличные от ISO8859-15, в несколько символов US-ASCII.

0 голосов
/ 01 октября 2015

Нашел документацию для команды TYPE :

Преобразование файла ASCII (Windows1252) в текстовый файл Unicode (UCS-2 le):

For /f "tokens=2 delims=:" %%G in ('CHCP') do Set _codepage=%%G    
CHCP 1252 >NUL    
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > unicode.txt 2>NUL    
CMD.EXE /D /U /C TYPE ascii_file.txt >> unicode.txt    
CHCP %_codepage%    

Приведенная выше методика (на основе сценария Карлоса М.) сначала создает файл с меткой порядка байтов (BOM), а затем добавляет содержимое исходного файла. CHCP используется для обеспечения того, что сеанс работает с кодовой страницей Windows1252, чтобы символы 0xFF и 0xFE (ÿþ) интерпретировались правильно.

0 голосов
/ 20 декабря 2010

Если вы уверены, что ваши файлы имеют формат UTF-8 или Windows 1252 (или Latin1), вы можете воспользоваться тем, что перекодирование завершится с ошибкой, если вы попытаетесь преобразовать неверный файл.

Хотя utf8 является действующим Win-1252, обратное неверно: win-1252 НЕ является действительным UTF-8. Итак:

recode utf8..utf16 <unknown.txt >/dev/null || recode cp1252..utf8 <unknown.txt >utf8-2.txt

Выпустит ошибки для всех файлов cp1252, а затем перейдет к преобразованию их в UTF8.

Я бы обернул это в более чистый скрипт bash, сохраняя резервную копию каждого преобразованного файла.

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

...