2012-11-05 40 views
5

Tôi có một số mã làm việc, nó rất đơn giản - nó sao chép mọi tệp * .jpg, đổi tên thành * 1.jpg, không phải lo lắng.Bash, chạy tập lệnh trên mọi tệp .jpg trong thư mục có thư mục con

for i in *.jpg; do cp $i ${i%%.jpg}1.jpg; done 

làm thế nào tôi có thể chạy này, vì vậy nó hoạt động trên tất cả các tập tin trong một thư mục, mỗi tập tin trong các thư mục con của thư mục đó

cấu trúc ví dụ thư mục:

test/test1/test2/somefile.jpg 
    test/anotherfile.jpg 
    test/test1/file.jpg 
etc 
+2

'mọi tệp trong thư mục con của thư mục đó' = đệ quy – nickhar

Trả lời

6

Các lệnh để làm bất cứ điều gì đệ quy cho cấu trúc thư mục là find:

find . -name "*.jpg" -exec bash -c 'file="{}"; cp "$file" "${file%%.jpg}1.jpg"' \; 

Sử dụng -exec thay vì for i in $(find ...) sẽ xử lý tên tệp có chứa khoảng trắng. Tất nhiên, vẫn còn một dấu trích dẫn; nếu tên tệp có chứa ", thì file="{}" sẽ mở rộng thành file="name containing "quote characters"", rõ ràng là bị hỏng (file sẽ trở thành name containing quote và nó sẽ cố gắng thực hiện lệnh characters).

Nếu bạn có tên tập tin như vậy, hoặc bạn có thể, sau đó in ra mỗi tên tập tin tách ra với các nhân vật null (mà không được phép vào tên tập tin) sử dụng -print0, và sử dụng while read -d $'\0' i để lặp qua các kết quả null-phân:

find . -name "*.jpg" -print0 | \ 
    (while read -d $'\0' i; do cp "$i" "${i%%.jpg}1.jpg"; done) 

Như với bất kỳ lệnh phức tạp nào như thế này, bạn nên kiểm tra nó mà không cần thực hiện bất cứ điều gì để đảm bảo nó mở rộng đến một cái gì đó hợp lý trước khi chạy nó. Cách tốt nhất để làm điều này là để thêm vào trước các lệnh thực tế với echo, vì vậy thay vì chạy nó, bạn sẽ thấy các lệnh đó nó sẽ chạy:

find . -name "*.jpg" -print0 | \ 
    (while read -d $'\0' i; do echo cp "$i" "${i%%.jpg}1.jpg"; done) 

Khi bạn đã eyeballed nó và kết quả có vẻ tốt, loại bỏ các echo và chạy nó một lần nữa để chạy nó cho thực tế.

+0

tìm. -name "* .jpg" -exec bash -c 'file = "{}"; cp "$ file" "$ {tệp %%. jpg} 1.jpg" '\; là tập lệnh chính xác, cảm ơn rất nhiều – user1051532

2

Nếu bạn có Bash 4, bạn có thể sử dụng globstar để cho phép mở rộng tên tập tin đệ quy (tức là phù hợp với tập tin trong thư mục con cũng)

shopt -s globstar 
for i in **/*.jpg; do cp "$i" "${i%%.jpg}1.jpg"; done 

p/s: tôi đã thêm dấu ngoặc kép quanh các đối số cho cp trong trường hợp có là khoảng trống trong tên tệp hoặc không có gì.

Các vấn đề liên quan