Mặc dù sedlà 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
findlà 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à readlệnh trong whilevòng lặp.
Các readlệnh được sử dụng để lấy đầu ra của findvà gán nó vào một biến, file. Thông thường, điều này sẽ gán giá trị cho filemỗ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 findbằng cách sử dụng -print0cờ).
Các vòng lặp while gây ra readviệc lặp lại các giá trị cho "tệp" cho mỗi tên tệp phù hợp. Các dovà donelà 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}.jpgthay đổi . filejpgthà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}.