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

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

пример использования recode:

recode windows-1252.. myfile.txt

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

10 ответов


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

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

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

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

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

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


вы можете использовать функцию iconv:

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


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

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

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


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

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

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

вам не нужно знать, что кодировка строк. Это может быть Latin1 (iso 8859-1), Windows-1252 или UTF8, или строка может иметь их сочетание. Кодировка::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

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


использовать iconv.

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


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

find . -name "*.txt" -exec iconv -f WINDOWS-1252 -t UTF-8 {} -o {}.ren \; -a -exec mv {}.ren {} \;

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

в то время как 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, сохраняя резервную копию каждого преобразованный файл.

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


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

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


нашел это документация для команды типа:

преобразование файла 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 (ÿþ) интерпретировались правильно.


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

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