На * Нікс без Perl rename
доступний
У деяких * nix перейменування немає, тому перейменувати потрібно, використовуючи якийсь інший метод. Кілька років тому я запропонував zmv
тут, що, хоч і чудово, теж не обов'язково доступне.
Використовуючи вбудовані та sed, ми можемо швидко пробити скрипт оболонки, щоб зробити це, що дає нам дуже схожий синтаксис із сценарієм перейменування perl, не маючи певної помилки обробки помилок, і це робить роботу.
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls $@); do
mv -v "$file" "$(sed $sed_pattern <<< $file)"
done
else
echo "usage: $0 sed_pattern files..."
fi
}
Використання
sedrename 's/Beethoven\ -\ //g' *.mp3
before:
./Beethoven - Fur Elise.mp3
./Beethoven - Moonlight Sonata.mp3
./Beethoven - Ode to Joy.mp3
./Beethoven - Rage Over the Lost Penny.mp3
after:
./Fur Elise.mp3
./Moonlight Sonata.mp3
./Ode to Joy.mp3
./Rage Over the Lost Penny.mp3
Скажімо, ми також хотіли створити цільові папки ...
Оскільки mv
папки не створюються, ми не можемо використовувати sedrename
її як тут, але це досить невелика зміна, тому я вважаю, що було б непогано включити і її.
Нам потрібна функція утиліти abspath
(або абсолютний шлях), щоб ми могли генерувати цільову папку для шаблону sed / rename, що включає нову структуру папок.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Це дозволить нам знати назви наших цільових папок. Коли ми перейменовуємось, нам потрібно буде використовувати його в імені цільового файлу.
# generate the rename target
target="$(sed $sed_pattern <<< $file)"
# Use absolute path of the rename target to make target folder structure
mkdir -p "$(dirname $(abspath $target))"
# finally move the file to the target name/folders
mv -v "$file" "$target"
Ось повний сценарій відомо про папки ...
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls $@); do
target="$(sed $sed_pattern <<< $file)"
mkdir -p "$(dirname $(abspath $target))"
mv -v "$file" "$target"
done
else
echo "usage: $0 sed_pattern files..."
fi
}
Звичайно, він все ще працює, коли у нас теж немає конкретних цільових папок.
Якщо ми хотіли скласти всі пісні в папку, ./Beethoven/
ми можемо зробити це:
Використання
sedrename 's|Beethoven - |Beethoven/|g' *.mp3
before:
./Beethoven - Fur Elise.mp3
./Beethoven - Moonlight Sonata.mp3
./Beethoven - Ode to Joy.mp3
./Beethoven - Rage Over the Lost Penny.mp3
after:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
Бонусний раунд ...
Використовуючи цей скрипт для переміщення файлів із папок у одну папку:
Припускаючи, що ми хотіли зібрати всі відповідні файли та розмістити їх у поточній папці, ми можемо це зробити:
sedrename 's|.*/||' **/*.mp3
before:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
after:
./Beethoven/ # (now empty)
./Fur Elise.mp3
./Moonlight Sonata.mp3
./Ode to Joy.mp3
./Rage Over the Lost Penny.mp3
Зверніть увагу на шаблони регулярного виразки
У цьому сценарії застосовуються регулярні правила шаблону sed, ці шаблони не є PCRE (сумісні з Perl регулярні вирази). Ви можете мати синтаксис регулярного регулярного вираження, використовуючи sed -r
або sed -E
залежно від вашої платформи.
Дивіться сумісність POSIX, man re_format
щоб отримати повний опис базових та розширених моделей регулярних викидів.