Кодировки-кодировочки

Денис Перехрест ненавидит кодировку windows-1251.

Скорее всего, он просто не умеет её готовить :)

По своему опыту знаю, что windows-1251 — это ещё не самое страшное зло. Гораздо страшнее, например, плеяда CJK-кодировок: GB2312, GBK, GB18030, EUC-TW, Big5, Shift_JIS, EUC-JP… Например, если открыть файл в кодировке windows-1251, как koi8-r сразу же станет ясно, что выбрана неправильная кодировка, тоже самое, если открыть utf-8, как iso-8859-1, но это абсолютно не так в случае с CJK-кодировками — они все показывают иероглифы (правда, каждый раз разные), поэтому если кодировка не указана явно, то догадаться о ней невозможно не только человеку (если он конечно не знаток языка), но и php mb_detect_encoding.

Слава Богу, что теперь Plesk перешёл на полную поддержку UTF-8 и кошмар с локализацией, а так же проблемы с поддержкой национальных символов завершились. Но до сих пор, время от времени, мне приходится перелопачивать большие объёмы файлов из одной кодировки в другую, например когда переводчики присылают материалы в кодировке, отличной от UTF-8.

Сейчас я расскажу (специально для Дениса и для всех, кому это модет пригодиться) о том как без особых усилий перекодировать файлы из кодировки windows-1251 в нашу любимую UTF-8.

Способ первый (ручной и неинтересный)

Откройте вашу любимую консоль (я предпочитаю rxvt-unicode, вы же можете открыть xterm или, если вы используете Windows, cmd.exe — кажется так)

Перейдите в директорию, где находятся файлы для перекодировки:

mv /path/to/your/files

Выполните слудующую команду:

iconv -f windows-1251 -t utf-8 <em>your_file</em> > <em>tmp_file</em>

где your_file — имя файла для перекодировки, а tmp_file — имя временного файла.

Утилита iconv входит в стандартную установку линукса, а если вы используете Windows, то вам следует установить порт iconv’а для win-32.

После этого, переименуйте временный файл:

mv <em>tmp_file</em> <em>your_file</em>

или (для Windows):

move <em>tmp_file</em> <em>your_file</em>

Это самый простой способ быстрой перкодировки одного-двух файлов.

Способ второй (попродвинутее)

Этот способ перекодирует все файлы в директории соответствующие шаблону.

Переходите в директорию набираете следующую команду (виндовозникам надо сперва установить утилиту find):

find . -name \*.php -exec iconv -f windows-1251 -t utf-8 {} > {}.tmp && mv {}.tmp {} \;

По сути, эта команда делает то же самое, что и в первом примере, но уже со всеми файлами, соответствующими шаблону (в нашем случае *.php)

Это довольно мощный способ перекодировки, но он неудобен тем, что он громоздкий и в нём легко ошибиться и, как результат испортить нужные данные. Поэтому предлагаю…

Способ третий

В этом примере мы создадим два скрипта: на bash и на php

win-1251-to-utf-8:

#!/bin/sh
usage="Usage win-1251-to-utf-8 filename
Converts filename from Windows-1251 to UTF-8"
if [ "$1" == "--help" ] ; then
        echo "$usage"
        exit 0
fi

if [ -z "$1" ] ; then
        echo "$usage"
        exit 1
else
        for file
        do
                TMP=`mktemp /tmp/win-1251-to-utf-8_XXXXXX`
                iconv -f windows-1251 -t utf-8 $file > $TMP && mv $TMP $file
        done
        exit 0
fi

win-1251-to-utf-8.php:

#!/usr/bin/php -q
<?php
    $usage = "Usage win-1251-to-utf-8 filename
Converts filename from Windows-1251 to UTF-8";

    if (count($argv) == 1 || $argv[1] == '-h' || $argv[1] == '--help') exit($usage);

    $args = $argv;
    unset($args[0]);

    foreach ($args as $arg) {
        $contents = file_get_contents($arg);
        $converted = iconv('windows-1251', 'utf-8', $contents);
        $f = fopen($arg, 'w');
        fwrite($f, $converted);
        fclose($f);
    }
?>

Вот и всё, осталось только установить у этих файлов права на запуск (на Linux):

chmod 755 win-1251-to-utf-8 win-1251-to-utf-8.php

и запускать на Линуксе

./win-1251-to-utf-8 <em>/path/to/files/*.*</em>

или

./win-1251-to-utf-8.php <em>/path/to/files/*.*</em>

или на Windows:

php win-1251-to-utf-8.php <em>/path/to/files/*.*</em>

4 комментариев к записи «Кодировки-кодировочки»


  1. Иконка граватара 1 Денис Перехрест

    спасибо, конечно, за способы перекодировки… Но как быть, если:
    - я нифига не понимаю в этих скриптах и программировании в целом?
    - нет желания устанавливать всякие порты iconv?
    - все текста находятся в базе?

    я бы с удовольствием рекомендовал “клиентам” ПРОСТОЙ СПОСОБ конвертировать их блоги в UTF-8, а потом уже делать дизайн исходя из utf-8…

  2. Иконка граватара 2 Пётр Шевцов

    Денис!

    Для того, чтобы разобраться в этих скриптах не надо быть мега-монстром в программировании.

    Установка порта iconv = скачать архив с бинарниками + распаковать архив + скопировать бинарники и библиотеки в $PATH (C:\WINDOWS\ если не путаю). Всё! Ничего страшного и невозможного.

    С базой данных тоже очень просто:
    создаёшь дамп базы данных:
    mysqldump --default-character-set=win1251 -C -u <strong>username</strong> -p -h host --opt --skip-add-locks --skip-extended-insert <strong>database</strong> &gt; dump.sql

    Конвертишь файл dump.sql из кодировки windows-1251 в UTF-8 по Первому способу:
    iconv -f windows-1251 -t UTF-8 dump.sql &gt; dump_utf8.sql

    А затем восстанавливаешь базу из дампа:
    mysql -u <strong>username</strong> -p --default-character-set=utf8 <strong>database</strong> &lt; dump_utf8.sql

    P.S. Не надо ничего рекоммендовать клиетнам — клиент всегда прав :) Если бы клиенты всегда всё делали правильно, то они бы всё далали сами и ни к кому бы не обращались :)

  3. Иконка граватара 3 Глеб

    А не проще сохранить файл в юникоде, а потом сменить расширение файла?

  4. Иконка граватара 4 Ирина

    ага, вам легко говорить.Я пока перекодировалась, столько матов выговорила. А вы легко, легко…

  1. 1 My hacking life at Stranger than Fiction
    Пингбэк отправлен 15 September:РП: 2007 года в 03:43

Оставить комментарий