ใน * ระวังไม่มี perl rename
ใช้ได้
ใน * ระวังไม่มีการเปลี่ยนชื่อจึงจำเป็นต้องทำการเปลี่ยนชื่อโดยใช้วิธีอื่น ไม่กี่ปีที่ผ่านมาฉันแนะนำzmv
ที่นี่ซึ่งในขณะที่ยอดเยี่ยมไม่จำเป็นต้องมีเช่นกัน
การใช้ builtins และ 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 / เปลี่ยนชื่อซึ่งรวมถึงโครงสร้างโฟลเดอร์ใหม่
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 regex
กฎรูปแบบ sed ทั่วไปที่ใช้ในสคริปต์นี้รูปแบบเหล่านี้ไม่ใช่ PCRE (นิพจน์ปกติที่เข้ากันได้กับ Perl) คุณสามารถเพิ่มไวยากรณ์นิพจน์ปกติได้โดยใช้อย่างใดอย่างหนึ่งsed -r
หรือsed -E
ขึ้นอยู่กับแพลตฟอร์มของคุณ
ดู POSIX compliant man re_format
สำหรับคำอธิบายที่สมบูรณ์เกี่ยวกับรูปแบบพื้นฐานและแบบขยาย regexp