Chúng tôi có thể cho rằng sed
nó có sẵn trên bất kỳ * nix nào, nhưng chúng tôi không thể chắc chắn rằng nó sẽ hỗ trợ sed -n
tạo các lệnh mv. ( LƯU Ý: Chỉ GNU mới sed
thực hiện điều này.)
Mặc dù vậy, bash nội trang và sed, chúng ta có thể nhanh chóng tạo một hàm shell để thực hiện điều này.
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|\(.*\)\(-[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
Tạo các thư mục đích:
Vì mv
không tự động tạo các thư mục đích nên chúng tôi không thể sử dụng phiên bản ban đầu của chúng tôi sedrename
.
Đó là một thay đổi khá nhỏ, vì vậy sẽ rất tuyệt nếu bao gồm tính năng đó:
Chúng tôi sẽ cần một chức năng tiện ích, abspath
(hoặc đường dẫn tuyệt đối) vì bash không có tích hợp này.
abspath () { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
Khi chúng ta có điều đó, chúng ta có thể tạo (các) thư mục đích cho một mẫu sed / rename bao gồm cấu trúc thư mục mới.
Điều này sẽ đảm bảo chúng tôi biết tên của các thư mục mục tiêu 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 đích.
# 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 như sau:
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
Phần thưởng vòng ...
Sử dụng tập lệnh này để di chuyển tệp từ các 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ề các mẫu regex cói
Quy tắc mẫu sed thông thường áp dụng trong tập lệnh này, những 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ể có cú pháp biểu thức chính quy mở rộng sed, sử dụng một trong hai 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 regexp cơ bản và mở rộng của sed.