Một câu trả lời phù hợp phụ thuộc vào cách các tên có thể khác nhau. Bạn có thể chuyển đổi tên bằng cách sử dụng thay thế tham số tích hợp của shell nếu bạn giả sử độ rộng trường không đổi. Đó là tương đối hạn chế về phạm vi.
Thú vị hơn là sử dụng các lớp nhân vật trong sed
:
newname=$(echo "$oldname" | sed -e 's/^\([[:alpha:]]\+\)\([[:digit:]]\+\)_/\1-\2-/')
nghĩa là, sau một tiền tố chữ cái hàng đầu, thêm dấu gạch ngang và sau đó sau các chữ số kết thúc bằng dấu gạch dưới, hãy thay đổi nó thành dấu gạch ngang.
Không giống như các giải pháp có thể sử dụng thay thế tham số, phương pháp này cho phép bất kỳ độ dài (khác không) từ tiền tố chữ số và chữ số. Vì vậy, bạn có thể có điều này như là đầu vào:
ABS1789_2563-01
ABS1789_2563-02
ABS1789_2563-02
ABSOLUTE1789_2563-01
ABSURD1789_2563-02
ABSOLVE1789_2563-02
PREFIX1793939389_2563-02
đặt nó trong một kịch bản
#!/bin/sh
for oldname in `cat foo4.txt`
do
newname=$(echo "$oldname" | sed -e 's/^\([[:alpha:]]\+\)\([[:digit:]]\+\)_/\1-\2-/')
echo "$oldname ->$newname"
done
đưa ra đầu ra này (trong một vòng lặp phù hợp):
ABS1789_2563-01 ->ABS-1789-2563-01
ABS1789_2563-02 ->ABS-1789-2563-02
ABS1789_2563-02 ->ABS-1789-2563-02
ABSOLUTE1789_2563-01 ->ABSOLUTE-1789-2563-01
ABSURD1789_2563-02 ->ABSURD-1789-2563-02
ABSOLVE1789_2563-02 ->ABSOLVE-1789-2563-02
PREFIX1793939389_2563-02 ->PREFIX-1793939389-2563-02
IFS
là không cần thiết, ngay cả khi các tệp của bạn có khoảng trắng (Tôi đã kiểm tra điều này trong Bash). Trong trường hợp chung (trong đó, không giống như ở đây, bạn không thể đảm bảo thay thế), có thể đáng để thử nghiệm[ "x$file" = "x$newfile" ] || mv -- "$file" "$newfile"
để tránhmv
phàn nàn về cũ và mới bằng nhau nếu không thay thế phù hợp (tôi cũng đã bảo vệ chống lại các tệp bắt đầu bằng-
, chúng tôi cũng bảo vệ biết sẽ không xảy ra trong trường hợp cụ thể này).