Auf einem * nix ohne Perl rename
verfügbar
Unter einigen * nix ist keine Umbenennung verfügbar, daher muss die Umbenennung mit einer anderen Methode durchgeführt werden. Vor ein paar Jahren habe ich zmv
hier vorgeschlagen , was zwar großartig ist, aber auch nicht unbedingt verfügbar ist.
Mit Builtins und Sed können wir schnell ein Shell-Skript erstellen, das uns eine sehr ähnliche Syntax wie das Perl-Umbenennungsskript bietet.
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
}
Verwendung
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
Angenommen, wir wollten auch Zielordner erstellen ...
Da mv
keine Ordner erstellt werden, die wir nicht verwenden können, sedrename
wie es hier ist, aber es ist eine ziemlich kleine Änderung, daher denke ich, dass es schön wäre, sie auch einzuschließen.
Wir benötigen eine Dienstprogrammfunktion abspath
(oder einen absoluten Pfad), damit wir die Zielordner für ein sed / rename-Muster generieren können, das eine neue Ordnerstruktur enthält.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Dadurch wird sichergestellt, dass wir die Namen unserer Zielordner kennen. Wenn wir umbenennen, müssen wir es für den Namen der Zieldatei verwenden.
# 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"
Hier ist das vollständige Ordner-fähige Skript ...
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
}
Natürlich funktioniert es immer noch, wenn wir auch keine bestimmten Zielordner haben.
Wenn wir alle Songs in einen Ordner legen wollten, können ./Beethoven/
wir dies tun:
Verwendung
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
Bonusrunde ...
Verwenden dieses Skripts zum Verschieben von Dateien aus Ordnern in einen einzelnen Ordner:
Angenommen, wir wollten alle übereinstimmenden Dateien sammeln und im aktuellen Ordner ablegen, dann können wir Folgendes tun:
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
Hinweis zu sed regex-Mustern
In diesem Skript gelten die Regeln für reguläre sed-Muster. Diese Muster sind keine PCRE (Perl Compatible Regular Expressions). Sie hätten die erweiterte Syntax für reguläre Ausdrücke entweder sed -r
oder sed -E
abhängig von Ihrer Plattform verwenden können.
man re_format
Eine vollständige Beschreibung der sed-Basis- und erweiterten Regexp-Muster finden Sie in der POSIX-Konformität .