Вы столкнетесь с некоторыми проблемами, если хотите переименовать файлы и каталоги одновременно. Переименовать только файл достаточно просто. Но вы хотите убедиться, что каталоги также переименованы. Вы не можете просто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
само по себе.
mv
уже существует, что может произойти (1), если у вас есть файлы, которые уже очищены (в результатеmv foo foo
), или (2), если у вас есть файлы с тем же именем, кроме для специальных символов (например, тамmv Encöding Encoding
, где у вас уже естьEncoding
файл в дополнение кEncöding
).Я знаю, что это не совсем то, что вы хотели, но если вы знаете оригинальную кодировку, возможно, вы можете использовать ее
convmv
для изменения кодировки на UTF-8, что должно решить большинство проблем.Это сработало для меня в папке с некоторыми неправильно закодированными польскими именами файлов:
Обратите внимание, что эта команда на самом деле ничего не переименовывает; добавить
--notest
опцию, чтобы действительно переименовать файлы.источник
convmv
вариант удивительно прост и идеален. Для OP, имеющего потенциальное множество кодировок, это могло бы быть объединено с другим ответом, так как,convmv
кажется, знает, когда он или когда он не встречает правильный формат. Циклически просматривая наборы символов,convmv --list
можно было бы их правильно закодировать.convmv -t utf8 --nfc -f iso-8859-1 --notest -r .
- Это--nfc
должно было соответствовать Linux, а не OS X или около того, просто ввод текстаconvmv
отказался от (полезных) опций.Я знаю, вы спрашивали о переименовании.
Но вы можете легко избежать этой проблемы с помощью программного обеспечения, такого как MusicBrainz Picard .
Он способен идентифицировать музыку (аудио-отпечатки пальцев), загружать все необходимые данные (включая изображения обложек, если таковые имеются) из огромной базы данных MusicBrainz и перемещать файлы так, чтобы ваша коллекция могла соответствовать любому шаблону, который вам нравится. Я использую его годами, и он всегда отлично работал с любым языком, от кириллического до арабского; и, конечно (по крайней мере, для латинских скриптов), он также может выполнять преобразование в ASCII.
При таком подходе на самом деле не имеет значения, насколько грязно / плохо названа ваша коллекция на самом деле, если файлы читаемы и полны.
(Я упоминал, что это бесплатно? Как в свободе слова, так и в свободном пиве? И программное обеспечение, и база данных ...?)
источник