Mặc dù sed
là một công cụ rất hữu ích và linh hoạt, nhưng bạn không sử dụng nó đúng cách. Nó được sử dụng tốt nhất để khớp và thay thế các chuỗi trong tệp văn bản; nó không thể đổi tên trực tiếp các tập tin trên hệ thống tập tin.
Nhiệm vụ này phù hợp hơn với bash one-liner (giả sử đó là vỏ của bạn). Để đổi tên một cái gì đó như . filejpg
để file.jpg
, sử dụng này:
find . -name '. *' -print0 | while read -d $'\0' file; do short_file=${file%jpg}.jpg; mv "$file" "${short_file:4}"; done
Giải trình
find
là một chương trình trả về các đường dẫn đến các tệp khớp với một thuộc tính tệp nhất định, trong trường hợp này là tên của tệp. Nếu tất cả những gì bạn muốn biết là những tập tin .jpg nào trong thư mục con của đường dẫn hiện tại của bạn, bạn sẽ làm find . -name "*.jpg"
. Thông thường, điều này xuất ra mỗi tệp trên một dòng mới. Thay vào -print0
đó, làm cho nó tách các trận đấu bằng một ký tự null. Điều này cho phép xử lý đúng tên tệp có khoảng trắng khi chúng ta chuyển đầu ra cho các lệnh tiếp theo.
Các |
nhân vật được gọi là một đường ống. Nó báo cho shell lấy đầu ra của lệnh bên trái và chuyển nó làm đầu vào cho lệnh bên phải, trong trường hợp này là read
lệnh trong while
vòng lặp.
Các read
lệnh được sử dụng để lấy đầu ra của find
và gán nó vào một biến, file
. Thông thường, điều này sẽ gán giá trị cho file
mỗi từ tại một thời điểm, nhưng -d $'\0'$
nguyên nhân khiến các bài tập được phân định bằng ký tự null (khớp với cách chúng tôi phân định các tệp find
bằng cách sử dụng -print0
cờ).
Các vòng lặp while gây ra read
việc lặp lại các giá trị cho "tệp" cho mỗi tên tệp phù hợp. Các do
và done
là một phần của cú pháp bash tiêu chuẩn cho một vòng lặp while:
while <something is true>; do
<run some commands>
done
Trong trường hợp này, trước tiên "chạy một số lệnh" của chúng tôi sẽ sửa phần mở rộng của tên tệp và gán nó cho một biến mới: short_file=${file%jpg}.jpg
thay đổi . filejpg
thành . file.jpg
. Sau đó, nó chạy mv
để đổi tên tập tin, loại bỏ .
phần đầu của tên tệp được sửa chữa mở rộng : mv "$file" ${short_file:2}
.