Wir können davon ausgehen, dass sed
es auf jedem * nix verfügbar ist, aber wir können nicht sicher sein, ob es sed -n
das Generieren von mv-Befehlen unterstützt. ( HINWEIS:sed
Dies wird nur von GNU durchgeführt .)
Trotzdem können wir schnell eine Shell-Funktion entwickeln, um dies zu tun.
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|\(.*\)\(-[0-9.]*\.pkg\)|\1\2|' *.pkg
before:
./Xft2-2.1.13.pkg
./jasper-1.900.1.pkg
./xorg-libXrandr-1.2.3.pkg
after:
./Xft2.pkg
./jasper.pkg
./xorg-libXrandr.pkg
Zielordner erstellen:
Da mv
Zielordner nicht automatisch erstellt werden, können wir unsere ursprüngliche Version von nicht verwenden sedrename
.
Es ist eine ziemlich kleine Änderung, daher wäre es schön, diese Funktion aufzunehmen:
Wir benötigen eine Utility-Funktion abspath
(oder einen absoluten Pfad), da bash diese Funktion nicht integriert hat.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Sobald wir das haben, können wir die Zielordner für ein sed / rename-Muster generieren, das eine neue Ordnerstruktur enthält.
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 keine spezifischen 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 .