Как массово переименовать файлы с неправильной кодировкой или массово заменить недопустимые закодированные символы?
У меня есть сервер Debian, и я размещаю музыку для интернет-радиостанции. У меня проблемы с именами файлов и путями, потому что многие файлы имеют неправильную кодировку, например:
./music/Bändname - Some Title - additional Info/B�ndname - 07 - This Title Is Cörtain, The EncÃding Not.mp3
В идеале хотелось бы удалить все что не есть буквы A-Z
/a-z
или цифры 0-9
или тире -
/нижнее подчеркивание _
... Результат должен выглядеть примерно так:
./music/Bndname-SomeTitle-additionalInfo/Bndname-07-ThisTitleIsCrtain,TheEncdingNot.mp3
Как добиться этого для большого количества файлов и каталогов?
Я видел такой же вопрос: массовое переименование (или правильное отображение) файлов со специальными символами
Но это только исправляет кодировку, я бы предпочел более строгий подход, как описано выше.
3 ответа
Вы столкнетесь с некоторыми проблемами, если хотите переименовать файлы и каталоги одновременно. Переименовать только файл достаточно просто. Но вы хотите убедиться, что каталоги также переименованы. Вы не можете просто mv Motörhead/Encöding Motorhead/Encoding
поскольку Motorhead
не будет существовать во время вызова.
Итак, нам нужно сначала просмотреть все файлы и папки, а затем переименовать только текущий файл или папку. Следующие работы с GNU find
и Bash 4.2.42 на моей OS X.
#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
d="$( dirname "$file" )"
f="$( basename "$file" )"
new="${f//[^a-zA-Z0-9\/\._\-]/}"
if [ "$f" != "$new" ] # if equal, name is already clean, so leave alone
then
if [ -e "$d/$new" ]
then
echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
ls -ld "$d/$new" "$d/$f"
else
echo mv "$file" "$d/$new" # remove "echo" to actually rename things
fi
fi
done
Вы можете изменить регулярное выражение, используя new="${f//[\\\/\:\*\?\"<>|]/}"
если вы хотите заменить что-то, что Windows не может обработать.
Сохранить этот скрипт как rename.sh
, сделайте его исполняемым с chmod +x rename.sh
, Затем назовите это как rename.sh /some/path
,
Обязательно разрешите любые конфликты имен файлов ("Notice
Анонсы).
Если вы абсолютно уверены, что он делает правильные замены, удалите echo
из сценария, чтобы фактически переименовать вещи вместо того, чтобы просто печатать, что они делают.
Чтобы быть в безопасности, я бы рекомендовал сначала проверить это на небольшом подмножестве файлов.
Варианты объяснены
Чтобы объяснить, что здесь происходит:
-depth
обеспечит повторный поиск каталогов по глубине, чтобы мы могли "свернуть" все с самого конца. Обычно,find
проходит по-разному (но не в ширину).-print0
обеспечиваетfind
вывод имеет нулевой разделитель, поэтому мы можем прочитать его сread -d ''
вfile
переменная. Это помогает нам справляться со всевозможными странными именами файлов, включая пробелы и даже переводы строк.- Мы получим каталог файла с
dirname
, Не забывайте всегда правильно указывать свои переменные в кавычках, иначе любой путь с пробелами или символами с пробелами сломает этот скрипт. - Мы получим фактическое имя файла (или имя каталога) с
basename
, - Затем мы удаляем любой недопустимый символ из
$f
используя возможности замены строк в Bash. Неверный означает все, что не является буквой в нижнем или верхнем регистре, цифрой, косой чертой (\/
), точка (\.
), подчеркивание или минус-дефис. - Если
$f
уже очищено (очищенное имя идентично текущему имени), пропустите его. - Если
$new
уже существует в каталоге$d
(например, у вас есть файлы с именемresume
а такжеrésumé
в том же каталоге), выдайте предупреждение. Вы не хотите его переименовывать, потому что в некоторых системахmv foo foo
вызывает проблему. Иначе, - Наконец мы переименовываем исходный файл (или каталог) в новое имя
Поскольку это будет действовать только на самой глубокой иерархии, переименование Motörhead/Encöding
в Motorhead/Encoding
делается в два этапа:
mv Motörhead/Encöding Motörhead/Encoding
mv Motörhead Motorhead
Это гарантирует, что все замены выполняются в правильном порядке.
Примеры файлов и тестовый прогон
Давайте предположим, что некоторые файлы в базовой папке test
:
test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule
Вот результат запуска в режиме отладки (с echo
напротив mv
), то есть команды, которые будут вызваны, и предупреждения о столкновении:
mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r-- … … test/work/resume
-rw-r—r-- … … test/work/résumé
Обратите внимание на отсутствие сообщений для with-hyphen.txt
, schedule
, а также test
сам.
Я знаю, что это не совсем то, что вы хотели, но если вы знаете оригинальную кодировку, возможно, вы можете использовать convmv
изменить кодировку на UTF-8, что должно исправить большинство проблем.
Это сработало для меня в папке с некоторыми неправильно закодированными польскими именами файлов:
convmv -f cp1250 -t utf8 -r .
Обратите внимание, что эта команда на самом деле ничего не переименовывает; добавлять --notest
Возможность действительно переименовать файлы.
Я знаю, вы спрашивали о переименовании.
Но вы можете легко избежать этой проблемы, используя программное обеспечение, такое как MusicBrainz Picard.
Он способен идентифицировать музыку (аудио-отпечатки пальцев), загружать все необходимые данные (включая изображения обложек, если таковые имеются) из огромной базы данных MusicBrainz и перемещать файлы так, чтобы ваша коллекция могла соответствовать любому шаблону, который вам нравится. Я использую его годами, и он всегда отлично работал с чем угодно, от кириллицы до арабского языка; и, конечно, (по крайней мере, для латинских сценариев) он также может выполнять преобразование в ASCII.
При таком подходе не имеет значения, насколько грязно / плохо названа ваша коллекция на самом деле, если файлы читаемы и полны.
(Я упоминал, что это бесплатно? Как в свободе слова, так и в свободном пиве? И программное обеспечение, и база данных...?)