Bulk recode filenames

Материал из KLUG
Перейти к: навигация, поиск

Массовая конвертация имен файлов и каталогов в другую кодировку

Если имена файлов и каталгов не в 7-битной ASCII-кодировке (латиница), то при их переносе между операционными системами с разными локальными кодировками их нормально читаемые имена могут стать нечитаемыми знаками. Одним из решений проблемы будет нижеописанный shell-скрипт.

Проблема возникла когда я передал товарищу скачанные из интернета файлы с именами в кириллице. На моей операционной системе (Linux) локаль UTF-8, а операционная система товарища использует кодировку cp1251. Соответственно переданные мною файлы у него нормально не отображались. Простой shell-скрипт рекурсивно конвертирует имена сколь угодно большой группы каталогов и файлов из одной кодировки в другую:

brecode.sh:

#!/bin/sh
# Bulk recode files and directories names to another encodings

# configuration
#RECODE_FROM="UTF8"    ## if commented out, then current locale is used
RECODE_TO="CP1251"     ## target encoding (mandatory)

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

# error handler
err()
{
    echo "$(basename ${0}): error: ${1}" >&2
    exit 1
}

# check utilities
for U in find iconv
do which ${U} >/dev/null || err "${U} utility not found"
done

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

    if test -d "${S}"
    then mkdir -p "${D}"  || err "mkdir failed"
    else cp "${S}" "${D}" || err "cp failed"
    fi
done

Скрипт не боится пробелов в названиях файлов. Для конвертации в качестве аргумента укажите каталог который надо конвертировать.
Рекурсивно переконвертированный каталог будет сохранен с именем <новая_кодировка>.ИСХОДНОЕ_ИМЯ рядом с указанным каталогом.

Например:

$ brecode.sh tmp/Мои\ файлы/

Готово. Смотрим что получилось:

$ ls -d tmp/CP1251.���\ �����/ | iconv -f cp1251
tmp/CP1251.Мои файлы/

Также может оказаться полезным временное перекодирование имен файлов или большого как по кол-ву файлов так и по объему хранилища. Для этого можно использовать специальную FUSE FS - fuse-convmvfs (в старых дистрибутивах может включаться без приставки fuse-, просто convmvfs). Использовать довольно просто:

 $ convmvfs /dst/temp/directory -o srcdir=/src/directory, icharset=utf8,ocharset=cp1251

Смотрим, копируем, архивируем как обычную директорию. Ну и чтобы отмонтировать:

 $ fusermount -u /dst/temp/directory
Личные инструменты
Пространства имён
Варианты
Действия
Навигация
Инструменты