Trên một * nix không có perl rename
có sẵn
Trên một số * nix không có đổi tên có sẵn, do đó, cần phải đổi tên bằng một số phương pháp khác. Một vài năm trước tôi đã đề nghị zmv
ở đây, trong khi tuyệt vời, không nhất thiết phải có sẵn.
Sử dụng nội trang và sed, chúng ta có thể nhanh chóng tạo ra một tập lệnh shell để thực hiện điều này, điều này mang lại cho chúng ta cú pháp rất giống với tập lệnh đổi tên perl, trong khi thiếu một số xử lý lỗi, nó sẽ hoàn thành công việc.
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
}
Sử dụng
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
Nói rằng chúng tôi cũng muốn tạo thư mục đích ...
Vì mv
không tạo các thư mục mà chúng tôi không thể sử dụng sedrename
như ở đây, nhưng đó là một thay đổi khá nhỏ, vì vậy tôi cho rằng cũng rất tốt nếu bao gồm nó.
Chúng ta cần một hàm tiện ích, abspath
(hoặc đường dẫn tuyệt đối) để chúng ta có thể tạo (các) thư mục đích cho mẫu sed / đổi tên bao gồm cấu trúc thư mục mới.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Điều này sẽ đảm bảo chúng tôi biết tên của các thư mục đích của chúng tôi. Khi chúng tôi đổi tên, chúng tôi sẽ cần sử dụng nó trên tên tệp mục tiêu.
# 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"
Đây là tập lệnh nhận biết thư mục đầy đủ ...
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
}
Tất nhiên, nó vẫn hoạt động khi chúng ta không có các thư mục đích cụ thể.
Nếu chúng tôi muốn đặt tất cả các bài hát vào một thư mục, ./Beethoven/
chúng tôi có thể làm điều này:
Sử dụng
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
Vòng thưởng ...
Sử dụng tập lệnh này để di chuyển tệp từ thư mục vào một thư mục:
Giả sử chúng tôi muốn thu thập tất cả các tệp phù hợp và đặt chúng vào thư mục hiện tại, chúng tôi có thể làm điều đó:
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
Lưu ý về mẫu sed regex
Các quy tắc mẫu sed thông thường được áp dụng trong tập lệnh này, các mẫu này không phải là PCRE (Biểu thức chính quy tương thích Perl). Bạn có thể sử dụng cú pháp biểu thức chính quy mở rộng, sử dụng sed -r
hoặc sed -E
tùy thuộc vào nền tảng của bạn.
Xem tuân thủ POSIX man re_format
để biết mô tả đầy đủ về các mẫu regrec cơ bản và mở rộng.