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

Кодировки


Рубрика: Дополнительные материалы -> Изучаем Linux -> Hужное/полезное
Метки: | | |
Просмотров: 9741

До сих пор время от времени сталкиваюсь с проблемами отображения текста в следствии зоопарка кодировок. Все проблемы решаются поиском в интернете и перебором различных способов, пока не находишь нужного результата! Мне это надоело и я решил собрать в 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. Из всего найденного мне понравился такой подход:

time find /www/server/ -name "*.html" -exec iconv -f=CP1251 -t=UTF-8 {} -o {} \; -exec echo {} \;

или

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 sed -i 's/windows-1251/UTF-8/g' {} \;

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

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. Как с ней работать, разобраться несложно ;)

Комментариев: 9 RSS

Конструкцию

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

find .  ! \( -name \*jpg -o -name \*png -o -name \*gif \)

спасибо за поправку! :) хотя, уже знаю )) прочитал комментарии на ЛОР. Вот-вот собирался внести это в статью или комментарий написать :)

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

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

find . -type f -exec chmod a-x {} \;
find /путь -type f -exec chmod a-x {} \;

сегодня обратилась сотрудница. Потеряла файл, который редактировала когда-то днём :) дело происходило в XFCE, в котором беда с поиском :) Так вот, проще всего было найти файл так:

find $HOME -mtime 0

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

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

find ./ -print | while read x ; do mv $x $(echo $x | tr 'A-Z' 'a-z'); done

Кодировки в названиях файлах можно менять и так:

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

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

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

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

Понадобилось сегодня следущее. Есть куча файлов html. Пару сотен их. Надо сделать что-то вроде карты сайта. То есть, из списка с названиями файлов сделать набор ссылок. Список сделать легко:

ls -1

Каждое название файла будет в отдельной строке. Осталось этот список обработать. Ну, тут sed нам поможет )

ls *htm* -1 | sed 's#\([a-z]*\).*#<a href="&">&</a>#g'

И получаем что-то вроде:

<a href="TMP962170103.htm">TMP962170103.htm</a>
<a href="TMP963389970.htm">TMP963389970.htm</a>
<a href="TMP966494650.htm">TMP966494650.htm</a>
<a href="TMPhj9cd9w5lw.htm">TMPhj9cd9w5lw.htm</a>
<a href="TMPwaiwu57uht.htm">TMPwaiwu57uht.htm</a>

Огромная дока по sed:

http://www.grymoire.com/Unix/Sed.html

помогла уже с первых страниц ))) Более объёмный материал едва ли ещё можно найти.

Алексей8 2015-12-27 в 03:53:16

Спасибо.

Повесьте на сайт контекстную рекламу, чтобы спасибы были более ощутимы :)

Владимир9 2016-12-09 в 04:24:44

Спасибо за Tag2Utf cyrillic mp3-tags decoder. Очень помог. Работает просто и без всяких проблем. А то пришлось бы действительно удалять все нечитаемые теги или править вручную. Или править по одному файлу, что тоже не очень...

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



 
(обязательно)