đệ quy thêm phần mở rộng tệp vào tất cả các tệp


106

Tôi có một vài thư mục và thư mục con chứa tệp không có phần mở rộng tệp. Tôi muốn thêm .jpgvào tất cả các tệp có trong các thư mục này. Tôi đã thấy các tập lệnh bash để thay đổi phần mở rộng tệp nhưng không chỉ để thêm một. Nó cũng cần phải được đệ quy, ai đó có thể giúp đỡ được không?

Câu trả lời:


228

Lệnh thay thế không có vòng lặp rõ ràng ( man find):

find . -type f -exec mv '{}' '{}'.jpg \;

Giải thích: điều này đệ quy tìm tất cả các tệp ( -type f) bắt đầu từ thư mục hiện tại ( .) và áp dụng lệnh move ( mv) cho mỗi tệp. Cũng lưu ý các dấu ngoặc kép xung quanh {}để các tên tệp có khoảng trắng (và thậm chí cả dòng mới ...) được xử lý đúng cách.


7
Đặc biệt, cái này hoạt động tốt hơn nếu có một số lượng lớn các tệp trong cấu trúc thư mục (khiến bash khó chịu về độ dài của danh sách các tệp cần lặp lại).
DrAl

@Al, nếu bạn đề cập đến một forbash đảo ngược vòng lặp để lặp qua danh sách các tệp, điều đó không chính xác. forVòng lặp bash lặp đi lặp lại mỗi mvlệnh.
nik 10/07/09

Câu hỏi: findĐầu tiên có thiết lập danh sách tệp trước khi nó thực hiện -execcâu lệnh không? Tôi đoán vậy, nhưng muốn hiểu rõ điểm này trước khi mã hóa các vòng lặp vô hạn.
Boldewyn

2
lệnh này cũng sẽ tìm các tệp có phần mở rộng. Đó có phải là những gì OP muốn?
ghostdog 74

1
@ ghostdog74: Vì anh ấy chấp nhận câu trả lời này, nên ở trên rõ ràng là đã lừa được. Nếu không, như bạn đã đề cập bên dưới, việc thêm -not -name "*.*"sẽ thực hiện thủ thuật.
Stephan202,

62

điều này sẽ tìm các tệp không có phần mở rộng và thêm .jpg của bạn

find /path -type f -not -name "*.*" -exec mv "{}" "{}".jpg \;

Điều này chắc chắn sẽ cung cấp kết quả mong muốn 99% thời gian. +1
les

9

Điều này hơi muộn, nhưng tôi nghĩ rằng tôi sẽ thêm rằng một giải pháp tốt hơn (mặc dù có thể ít đọc hơn) so với những giải pháp cho đến nay có thể là:

find /path -type f -not -name "*.*" -print0 | xargs -0 rename 's/(.)$/$1.jpg/'

Sử dụng find | xargsmẫu thường dẫn đến việc thực thi hiệu quả hơn, vì bạn không phải phân nhánh một quy trình mới cho mỗi tệp.

Lưu ý rằng điều này yêu cầu phiên bản đổi tên được tìm thấy trong các bản phân phối có hương vị Debian (hay còn gọi là tên trước), thay vì đổi tên truyền thống. Tuy nhiên, nó chỉ là một tập lệnh perl nhỏ, vì vậy sẽ đủ dễ dàng để sử dụng lệnh trên trên bất kỳ hệ thống nào.


4

như thế này,

for f in $(find . -type f); do mv $f ${f}.jpg; done

Tôi không mong đợi bạn có các tên tệp được phân tách bằng dấu cách,
Nếu bạn làm vậy, các tên sẽ cần được xử lý một chút.

Nếu bạn muốn thực hiện lệnh từ một số thư mục khác,
bạn có thể thay thế find .bằng find /target/directory.


1
Điều này bị thiếu "do" và nếu có khoảng trắng trong tên tệp, tốt hơn nên trích dẫn tên tệp: for f in $ (find. -Type f); làm mv "$ f" "$ {f} .jpg"; thực hiện
DrAl

và có lẽ tôi sẽ chạy nó từ trong thư mục cấp cao nhất?
robjmills

@seengee: vâng. Lưu ý rằng lệnh này cũng bỏ sót dấu gạch ngang -type.
Stephan202

Tôi đã phải đi đâu đó và gõ quá nhanh ... đang sửa ngay.
nik

1

Để đổi tên tất cả các tệp không có phần mở rộng trong Windows cơ bản, bạn có thể thực hiện ren * *.jpg Vì tệp không có phần mở rộng, chỉ cần sử dụng dấu * hoặc nếu bạn muốn thay đổi png thành jpgren *.png *.jpg


0

rename

không chắc rằng nó có thể đổi tên tệp mà không có phần mở rộng (tôi đang sử dụng windows 7 ngay bây giờ)


1
nó có thể, nhưng nó cũng sẽ đổi tên các thư mục và không có cách nào để yêu cầu nó hoạt động đệ quy trong các thư mục con (ít nhất là với phiên bản tôi có trên Ubuntu).
mirod

Tôi biết có ít nhất hai lệnh khác nhau được gọi rename, một lệnh là chương trình C có trong use-linux-ng và một là chương trình Perl (của chính Wall) trên máy Debian của trường đại học chúng tôi. Trên thực tế, cả hai đều không đệ quy.
Boldewyn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.