Câu hỏi Đổi tên tất cả các tệp trong các thư mục phụ


Tôi gặp sự cố khi viết tập lệnh để đổi tên hàng loạt tệp trong thư mục con.

Tôi có một thư mục với nhiều thư mục con và các thư mục con đó có nhiều tệp mà tôi cần đổi tên.

Đây là nơi tôi đã có cho đến nay:

for file in $(find -name "*.report")
do
  mv "$file" "LPP_${file/LP_/}"
done

Như bạn có thể thấy, tôi cần phải thay thế chuỗi 'LP_' trong tên tệp bằng 'LPP_'.

Điều này không hoạt động vì đường dẫn đến tệp - các chuỗi được truy lục từ lệnh find chỉ là các tên tệp và không bao gồm đường dẫn. Để bao gồm đường dẫn, tôi đang thử một cái gì đó như thế này:

for file in $(find -name "*.report")
do
  echo "$file" 
  echo "${RELPATH/\$\//}/${file/LP_/LPP_}"
done

Nhưng biến RELPATH là tiền tố một ký tự '/', do đó lệnh mv đang phàn nàn rằng nó không thể di chuyển tệp đến /./subfolder1/LPP_filename.report

Ai đó có thể cho tôi biết những gì tôi đang làm sai, là có một cách tốt hơn để làm điều đó, và giải thích tại sao có thêm một '/' nhân vật trong biến RELPATH te và làm thế nào để loại bỏ nó?

Trước tiên xin cảm ơn tất cả các bạn!


2
2017-11-14 19:16


gốc


Chỉ cần một đầu lên: rằng cho vòng lặp sẽ không hoạt động trong các tệp / thư mục có tên chứa không gian! Bạn nên sử dụng một cái gì đó giống như những gì thợ sắt gợi ý trong câu trả lời của anh ta.
tốt, tôi có thể xem xét để bắt đầu sử dụng python cho các công cụ như thế này, nhưng trước tiên bạn có thể chỉ cho tôi một số tài liệu về cách thiết lập nó? Tôi có thể sử dụng windows cmd, bất cứ thứ gì. Tôi đang tìm thứ gì đó mà tôi sẽ sử dụng trong tương lai, tôi nghĩ git bash là đủ tốt để bắt đầu. - sskular


Các câu trả lời:


Tôi thực sự không hiểu vấn đề của bạn (find  Nên trả lại đường dẫn đầy đủ), tuy nhiên tôi đề xuất một cách tiếp cận khác, có lẽ một cái gì đó như

find -name '*.report' -execdir bash -c 'echo mv "$0" "${0/LP_/LPP_}"' {} \;

Bằng cách truyền find kết quả {} như một tham số vị trí vỏ $0 cho cấp dưới bash -c lệnh, chúng ta có thể làm việc xung quanh thực tế là chúng ta không thể làm mv {} ${{}/LP_/LPP_} trực tiếp. Việc sử dụng -execdir thay vì phổ biến hơn -exec đảm bảo rằng sự thay thế chỉ xảy ra trên phần tên tệp, trong trường hợp bất kỳ đường dẫn nào xảy ra chứa chuỗi LP_

Các echo chỉ là để bạn có thể dùng thử và kiểm tra xem việc đổi tên có đúng không - bạn sẽ cần xóa nó để cho phép đổi tên thực sự.


2
2017-11-14 19:32



Khi tôi chạy nó trong bash, nó nói: find: invalid predicate `-execdir 'khi tôi chỉ chạy lệnh find, nó không thể tìm thấy bất kỳ tập tin nào, và có các tập tin trong đó, trong các thư mục con. Tôi đang sử dụng git bash được cài đặt trên máy tính windows của tôi. - sskular
Cảm ơn vì gợi ý về lệnh tìm kiếm, nó phải quá muộn để tôi suy nghĩ đúng đắn, không biết làm thế nào tôi bỏ lỡ nó. Đây là mã mà tôi quản lý để kéo nó ra: for file in $(find -name "*.report") do mv "$file" "${file/LP_/LPP_}" done Nếu bạn có thể cung cấp thêm một số chi tiết xung quanh câu trả lời của bạn, và có thể bao gồm cách tiếp cận này trong câu trả lời là tốt và sau đó tôi sẽ đánh dấu câu trả lời của bạn là câu trả lời tốt nhất. Cảm ơn đã giúp đỡ!! - sskular
@sskular có 2 vấn đề với mã trong bình luận của bạn ở trên: (1) nó sẽ phá vỡ nếu bất kỳ đường dẫn nào chứa một khoảng trống (tách từ); và (2) nó sẽ cố gắng đổi tên Đầu tiên thể hiện của LP_ bất cứ nơi nào trong đường dẫn như vậy cũng sẽ phá vỡ nếu bất kỳ tên thư mục con nào xảy ra bao gồm chuỗi LP_. Nếu nó hoạt động cho trường hợp của bạn là tốt - nhưng nó không phải là một giải pháp mạnh mẽ nói chung. - steeldriver