<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="article.xsl"?>
<article lang="ru">
        <meta>
                <title>Bulk FileNames Recode</title>
        </meta>
        <content>
                <head>
                        <heading>Массовая конвертация имен файлов и каталогов в другую кодировку</heading>
                        <author name="maretskiy"/>
                        <created>2009.07.16</created>
                        <updated>2009.09.03</updated>
                        <description>Если имена файлов и каталгов не в 7-битной ASCII-кодировке (латиница), то при их переносе между операционными системами с разными локальными кодировками их нормально читаемые имена могут стать нечитаемыми знаками. Одним из решений проблемы будет нижеописанный shell-скрипт.</description>
                </head>
                <body>
                        <caption></caption>
                        <p>Проблема возникла когда я передал товарищу скачанные из интернета файлы с именами в кириллице. На моей операционной системе (Linux) локаль UTF-8, а операционная система товарища использует кодировку cp1251. Соответственно переданные мною файлы у него нормально не отображались. Простой <a href="brecode.sh">shell-скрипт</a> рекурсивно конвертирует имена сколь угодно большой группы каталогов и файлов из одной кодировки в другую:</p>
                        <prec><a href="brecode.sh">brecode.sh</a></prec>
                        <code>#!/bin/sh
<comment>## brecode version 20090903
## Bulk recode files and directories names to another encodings</comment>

<comment>#### configuration</comment>
<comment>#RECODE_FROM=&quot;UTF8&quot;    ## if commented out, then current locale is used</comment>
RECODE_TO=<string>&quot;CP1251&quot;</string>     <comment>## target encoding (mandatory)</comment>

<comment>#### check argument</comment>
if ! test -d <string>&quot;${1}&quot;</string>
then
    echo <string>&quot;Bulk recode files and directories names to another encodings&quot;</string> &gt;&amp;2
    echo <string>&quot;  Current RECODE_FROM=${RECODE_FROM}&quot;</string> &gt;&amp;2
    echo <string>&quot;  Current RECODE_TO=${RECODE_TO}&quot;</string> &gt;&amp;2
    echo <string>&quot;Usage:&quot;</string> &gt;&amp;2
    echo <string>&quot;  $(basename ${0}) &lt;what/needed/to/be/recoded&gt;&quot;</string> &gt;&amp;2
    exit 1
fi

<comment>#### error handler</comment>
err()
{
    echo <string>&quot;$(basename ${0}): error: ${1}&quot;</string> &gt;&amp;2
    exit 1
}

<comment>#### check utilities</comment>
for U in find iconv
do which ${U} &gt;/dev/null || err <string>&quot;${U} utility not found&quot;</string>
done

<comment>#### recode and copy</comment>
cd $(dirname <string>&quot;${1}&quot;</string>) || exit 1
T=$(basename <string>&quot;${1}&quot;</string>)
find <string>&quot;${T}&quot;</string> | while read S
do
    if test ${RECODE_FROM}
    then D=<string>&quot;${RECODE_TO}.$(echo ${S} | iconv -f ${RECODE_FROM} -t ${RECODE_TO})&quot;</string>
    else D=<string>&quot;${RECODE_TO}.$(echo ${S} | iconv -t ${RECODE_TO})&quot;</string>
    fi

    if test -d <string>&quot;${S}&quot;</string>
    then mkdir -p <string>&quot;${D}&quot;</string>  || err <string>&quot;mkdir failed&quot;</string>
    else cp <string>&quot;${S}&quot;</string> <string>&quot;${D}&quot;</string> || err <string>&quot;cp failed&quot;</string>
    fi
done</code>
                        <p>Скрипт не боится пробелов в названиях файлов. Для конвертации в качестве аргумента укажите каталог который надо конвертировать. Рекурсивно переконвертированный каталог будет сохранен с именем &lt;новая_кодировка&gt;.ИСХОДНОЕ_ИМЯ рядом с указанным каталогом. Например:</p>
                        <shell>$ brecode.sh tmp/Мои\ файлы/</shell>
<p>Готово. Смотрим что получилось:</p>
                        <shell>$ ls -d tmp/CP1251.���\ �����/ | iconv -f cp1251
tmp/CP1251.Мои файлы/</shell>
                </body>
        </content>
</article>

