เราสามารถสันนิษฐานได้ว่าsed
มีอยู่ใน * nix ใด ๆ แต่เราไม่แน่ใจว่าจะรองรับsed -n
การสร้างคำสั่ง mv ( หมายเหตุ: GNU เท่านั้นที่sed
ทำสิ่งนี้ได้)
ถึงกระนั้นก็ตาม bash builtins และ sed เราสามารถแส้ฟังก์ชันเชลล์เพื่อทำสิ่งนี้ได้อย่างรวดเร็ว
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|\(.*\)\(-[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
การสร้างโฟลเดอร์เป้าหมาย:
เนื่องจากmv
ไม่ได้สร้างโฟลเดอร์เป้าหมายโดยอัตโนมัติเราจึงไม่สามารถใช้เวอร์ชันเริ่มต้นของเราsedrename
ได้
เป็นการเปลี่ยนแปลงที่ค่อนข้างเล็กดังนั้นจึงเป็นการดีที่จะรวมคุณลักษณะดังกล่าว:
เราจะต้องมีฟังก์ชั่นยูทิลิตี้abspath
(หรือพา ธ สัมบูรณ์) เนื่องจาก bash ไม่มีบิลด์นี้
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
เมื่อเรามีแล้วเราสามารถสร้างโฟลเดอร์เป้าหมายสำหรับรูปแบบ sed / เปลี่ยนชื่อซึ่งรวมถึงโครงสร้างโฟลเดอร์ใหม่
เพื่อให้แน่ใจว่าเราทราบชื่อโฟลเดอร์เป้าหมายของเรา เมื่อเราเปลี่ยนชื่อเราจะต้องใช้มันกับชื่อไฟล์เป้าหมาย
# 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 Compatible Regular Expressions) คุณสามารถขยายไวยากรณ์นิพจน์ทั่วไปได้โดยใช้อย่างใดอย่างหนึ่งsed -r
หรือsed -E
ขึ้นอยู่กับแพลตฟอร์มของคุณ
ดูที่สอดคล้องกับ POSIX man re_format
สำหรับคำอธิบายที่สมบูรณ์ของรูปแบบ regexp พื้นฐานและส่วนขยาย sed