GNU/Linux -- это интересно

Кодировки

Рубрика: Hужное/полезное
Метки: | |
Суббота, 19 декабря 2009 г.
Просмотров: 4253
Подписаться на комментарии по RSS

До сих пор время от времени сталкиваюсь с проблемами отображения текста в следствии зоопарка кодировок. Все проблемы решаются поиском в интернете и перебором различных способов, пока не находишь нужного результата...

Мне это надоело и я решил собрать в oдном мecтe проверенные решения.

Начнём с кодировок в названиях файлов.

Если нам нужно перекодировать раздел с виндовыми файлами в правильную кодировку, то необходимо выполнить следующее:

convmv -r -f cp1251 -t utf-8 --notest

Без параметра --notest процесс пройдёт лишь в тестовом режиме. С этим же параметром все изменения будут записаны на файловую систему. Сам convmv должен быть предварительно установлен.

Иногда бывают ситуации, когда нужно избавиться от названий файлов, в которых присутствует кириллица. Тут тоже всё просто. Создаём файл со следующим содержанием и выполняем его:

#!/bin/bash
# Перекодирует рекурсивно в текущем каталоге имена
# файлов и каталогов в транслит.
shopt -s nullglob
for NAME in *.mp3 ; do
  TRS=`echo $NAME | sed "y/абвгдезийклмнопрстуфхцы/abvgdezijklmnoprstufxcy/"`
  TRS=`echo $TRS  | sed "y/АБВГДЕЗИЙКЛМНОПРСТУФХЦЫ/ABVGDEZIJKLMNOPRSTUFXCY/"`
  TRS=${TRS//ч/ch};
  TRS=${TRS//Ч/CH} TRS=${TRS//ш/sh};
  TRS=${TRS//Ш/SH} TRS=${TRS//ё/jo};
  TRS=${TRS//Ё/JO} TRS=${TRS//ж/zh};
  TRS=${TRS//Ж/ZH} TRS=${TRS//щ/sh\'};
  TRS=${TRS//Щ/SH\'} TRS=${TRS//э/je};
  TRS=${TRS//Э/JE} TRS=${TRS//ю/ju};
  TRS=${TRS//Ю/JU} TRS=${TRS//я/ja};
  TRS=${TRS//Я/JA} TRS=${TRS//ъ/\`};
  TRS=${TRS//ъ\`} TRS=${TRS//ь/\'};
  TRS=${TRS//Ь/\'}
  if [[ `file -b "$NAME"` == directory ]]; then
    mv -v "$NAME" "$TRS"
    cd "$TRS"
    "$0"
    cd ..
  else
    mv -v "$NAME" "$TRS"
  fi
done

Всё просто.

А вот ещё задача. Ну просто огромная куча текстовых файлов в какой-то кодировке. Допустим, в той же cp1251. А нам нужно всё это добро конвертировать во всё ту же незаменимую UTF-8. Из всего найденного мне понравился такой подход:

find . | while read i; do iconv -f  WINDOWS-1251 -t UTF-8 "$i" >tmp; mv tmp "$i"; done

Будут конвертированы все файлы во всех вложенных директориях. Только учтите, что и бинарные файлы (например, картинки) тоже будут "конвертированы", то есть повреждены. Поэтому, если у вас всё вперемешку, то нужно из поиска их исключить. Как? После "find . | " дописать что-то вроде:

grep -v png | grep -v jpg | grep -v gif |

То есть, начало будет такое:

find . | grep -v png | grep -v jpg | grep -v gif | while read i; do ......

Или, если конвертировать в юникод нужно только php-файлы, то достаточно сделать так:

find . -name '*.php' | while read i; do iconv -f  WINDOWS-1251 -t UTF-8 "$i" \
 >tmp; mv tmp "$i"; done

Где такое могло понадобится? А, например, старый сайт был создан ещё тогда, когда многие про юникод ничего не знали. Следовательно, конвертирование - это ещё не всё. Нужно найти все упоминание корня всех проблем - windows-1251. Ну, тут проще простого:

grep -ir windows-1251 .

Точка в конце означает, что искать команда будет с текущей директории. Опции же -ir помогают нам вывести на экран все значения не зависимо от регистра, притом поиск будет рекурсивным (во всех вложенных директориях).

Увидели результат. Допустим, у нас искомое было в файлах типа *.php. Хорошо, тогда мы в них и произведём замену:

find . -name "*.php" -exec sh -c 'sed "s/windows-1251/UTF-8/g" "{}" \
           > tmpfile && mv tmpfile "{}"' \;

Теперь ещё раз проверяем, достигли ли мы успеха:

grep -ir windows-1251 .

Всё, в этом случае больше ничего не должно вывестись на экран. Только, если не будут найдены совпадения в других файлах, которые не *.php. Тогда придётся повторить операцию и с ними. После чего можно тестировать свой старый сайт =)

Что ещё часто нам режет глаза обилием иероглифов? Конечно же теги в mp3-файлах. До сих пор находятся умельцы, которые их сохраняют в cp1251. Кривые руки таких творцов не выпрямишь, зато ошибки оных легко исправить! Устанавливаем пакет python-mutagen и пприступаем к преобразованию:

find -iname '*.mp3' -print0 | xargs -0 mid3iconv -eCP1251 --remove-v1

Ещё вариант, но не использующий xargs:

find . -iname “*.mp3″ -exec mid3iconv -e CP1251 -d –remove-v1 {} ;

Вырезаются все теги id3v1, прописанные в cp1251 кодировке.

Есть ещё некий Tag2Utf cyrillic mp3-tags decoder - это скрипт на Python, который рекурсивно сканирует директорию, в которой запущен, и конвертирует все теги содержащие cp1251 и koi8-r в UTF-8. Для работы требует python-eyed3.

Для работы с тегами есть хорошая графическая программа EasyTag. Как с ней работать, разобраться несложно ;)

Автор: vovans, xmpp: xmpp
Добавить страницу в закладки:
twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru ya.ru rutvit.ru myspace.com technorati.com digg.com friendfeed.com pikabu.ru blogger.com liveinternet.ru livejournal.ru memori.ru google.com bobrdobr.ru mister-wong.ru yahoo.com yandex.ru del.icio.us
Комментариев: 6
  1. Конструкцию

    find . | grep -v png | grep -v jpg | grep -v gif
    можно оптимизировать, задав условия еще на этапе выполнения find:

    find .  ! \( -name \*jpg -o -name \*png -o -name \*gif \)
  2. спасибо за поправку! :) хотя, уже знаю )) прочитал комментарии на ЛОР. Вот-вот собирался внести это в статью или комментарий написать :)

    Ещё раз спасибо!

  3. ещё, бывает, исходники некоторые несознательные товарищи распространают в виде zip-архивов. Распаковываем такой архив и получаем нужный набор файлов с правами на выполнение... Как убрать рекурсивно у всех файлов бит на выполнение, но так, чтобы это не затронуло вложенные директории?

    find . -type f -exec chmod a-x {} \;
    find /путь -type f -exec chmod a-x {} \;
  4. сегодня обратилась сотрудница. Потеряла файл, который редактировала когда-то днём :) дело происходило в XFCE, в котором беда с поиском :) Так вот, проще всего было найти файл так:

    find $HOME -mtime 0

    в хомяке будут найдены все файлы, которые модифицировались последние сутки! ;)

  5. Есть ещё одна интересная задача, не имеющая отношения к кодировкам, но как пример использования find. Для игры Seven Kingdoms: Ancient Adversaries понадобилось все файлы ресурсов перегнать из верхнего в нижний регистры. Всё просто :)

    find ./ -print | while read x ; do mv $x $(echo $x | tr 'A-Z' 'a-z'); done
  6. Кодировки в названиях файлах можно менять и так:

    устанавливаем nautilus-filename-repairer

    http://code.google.com/p/repairer/

    http://packages.ubuntu.com/ru/maverick/nautilus-filename-repairer

    Перезапускаем наутилус и .. Красота!

Оставьте комментарий!
Используйте нормальные имена.
Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий email.
(При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где вы сможете изменить свои данные, включая адрес сайта, ник, описание, контакты и т.д.)




Войти через loginza

 
captcha