Perl olmadan * nix üzerinde rename
kullanılabilir
Bazı * nix'lerde yeniden adlandırma yoktur, bu nedenle başka bir yöntem kullanarak yeniden adlandırma yapmanız gerekir. Birkaç yıl önce, zmv
burada harika olsa da mutlaka uygun olmadığını da önerdim.
Builtins ve sed komutunu kullanarak hızlıca bir kabuk betiği hazırlayabiliriz, bu da bize perl yeniden adlandırılan betiğe çok benzer bir sözdizimi verir, bazı hata işlemlerinde ustalıktan yoksun kalırken, işi halleder.
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
}
kullanım
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
Diyelim ki biz de hedef klasörler oluşturmak istedik ...
Burada olduğu mv
gibi kullanamayacağımız klasörleri oluşturmadığından sedrename
, ancak oldukça küçük bir değişiklik olduğu için onu da eklemenin iyi olacağını düşünüyorum.
Bir yardımcı program işlevine abspath
(ya da mutlak yol) ihtiyacımız var, böylece yeni klasör yapısını içeren sed / rename modeli için hedef klasörleri oluşturabiliriz.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Bu, hedef klasörlerimizin isimlerini bilmemizi sağlayacaktır. Yeniden adlandırdığımızda, onu hedef dosya adında kullanmamız gerekecek.
# 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"
İşte tam klasör farkında komut dosyası ...
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
}
Tabii ki, belirli hedef klasörlerimiz de olmadığında hala çalışıyor.
Bütün şarkıları bir klasöre koymak istiyorsak ./Beethoven/
bunu yapabiliriz:
kullanım
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
Bonus turu ...
Dosyaları klasörlerden tek bir klasöre taşımak için bu komut dosyasını kullanma:
Eşleştirilen tüm dosyaları toplamak ve bunları geçerli klasöre koymak istediğimizi varsayarsak, bunu yapabiliriz:
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 regex desenleriyle ilgili not
Bu betiğe düzenli sed desen kuralları uygulanır, bu desenler PCRE değildir (Perl Uyumlu Düzenli İfadeler).
Platformunuza bağlı olarak sed -r
veya birini kullanarak, düzenli ifade sözdizimini genişletmiş olabilirsiniz sed -E
.
man re_format
Sed basic ve genişletilmiş regexp kalıplarının tam bir açıklaması için POSIX uyumluya bakın .