Kami dapat berasumsi sed
tersedia di * nix apa pun, tetapi kami tidak dapat memastikan itu akan mendukung sed -n
untuk menghasilkan perintah mv. ( CATATAN: Hanya GNU yang sed
melakukan ini.)
Meski begitu, bash builtins dan sed, kita dapat dengan cepat menyiapkan fungsi shell untuk melakukan ini.
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
}
Pemakaian
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
Membuat folder target:
Karena mv
tidak secara otomatis membuat folder target, kami tidak dapat menggunakan versi awal kamisedrename
.
Ini adalah perubahan yang cukup kecil, jadi akan menyenangkan untuk menyertakan fitur itu:
Kita memerlukan fungsi utilitas, abspath
(atau jalur absolut) karena bash tidak memiliki build ini.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Setelah kita memilikinya, kita dapat menghasilkan folder target untuk pola sed / rename yang menyertakan struktur folder baru.
Ini akan memastikan kami mengetahui nama folder target kami. Saat kami mengganti nama, kami harus menggunakannya pada nama file target.
# 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"
Inilah skrip sadar folder lengkap ...
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
}
Tentu saja, ini masih berfungsi ketika kami tidak memiliki folder target tertentu juga.
Jika kami ingin memasukkan semua lagu ke dalam folder, ./Beethoven/
kami dapat melakukan ini:
Pemakaian
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
Putaran bonus ...
Menggunakan skrip ini untuk memindahkan file dari folder ke dalam satu folder:
Dengan asumsi kami ingin mengumpulkan semua file yang cocok, dan menempatkannya di folder saat ini, kami dapat melakukannya:
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
Perhatikan pola sed regex
Aturan pola sed reguler berlaku dalam skrip ini, pola ini bukan PCRE (Perl Compatible Regular Expressions). Anda bisa saja memperluas sintaks ekspresi reguler, menggunakan salah satu sed -r
atau sed -E
bergantung pada platform Anda.
Lihat kepatuhan POSIX man re_format
untuk penjelasan lengkap tentang pola regexp dasar sed dan diperpanjang.