Cách hiệu quả nhất để di chuyển một số lượng lớn các tệp nằm trong một thư mục là gì?


11

CentOS 5.x

Tôi xin lỗi nếu đây là một câu hỏi lặp lại. Tôi đã thấy rất nhiều câu hỏi tương tự (liên quan đến việc xóa các tệp) nhưng không chính xác cùng một kịch bản.

Tôi có một thư mục chứa hàng trăm ngàn tệp (có thể hơn một triệu) và để khắc phục ngắn hạn cho một vấn đề khác, tôi cần di chuyển các tệp này sang vị trí khác.

Với mục đích thảo luận, giả sử các tệp này ban đầu cư trú /home/foo/bulk/và tôi muốn chuyển chúng sang/home/foo2/bulk2/

Nếu tôi thử, mv /home/foo/bulk/* /home/foo2/bulk2/ tôi gặp lỗi "quá nhiều đối số".

Ông Google nói với tôi rằng một giải pháp thay thế để xóa các tệp hàng loạt sẽ là chạy find. Cái gì đó như: find . -name "*.pdf" -maxdepth 1 -print0 | xargs -0 rm

Sẽ ổn thôi nếu tôi xóa nội dung nhưng trong trường hợp này tôi muốn di chuyển các tệp ... Nếu tôi gõ một cái gì đó như find . -name "*" -maxdepth 1 -print0 | xargs -0 mv /home/foo2/bulk2/bash phàn nàn về việc tệp không phải là một thư mục.

Lệnh tốt nhất để sử dụng ở đây để di chuyển các tệp hàng loạt từ thư mục này sang thư mục khác là gì?

Câu trả lời:


16

Lợi dụng GNU mv's -ttùy chọn để chỉ định thư mục đích, thay vì dựa vào lập luận lần cuối:

find . -name "*" -maxdepth 1 -exec mv -t /home/foo2/bulk2 {} +

Nếu bạn đang ở trên một hệ thống không có tùy chọn, bạn có thể sử dụng trình bao trung gian để nhận các đối số theo đúng thứ tự ( find … -exec … +không hỗ trợ đặt các đối số bổ sung sau danh sách các tệp).

find . -name "*" -maxdepth 1 -exec sh -c 'mv "$@" "$0"' /home/foo2/bulk2 {} +

Bạn có thể sử dụng find ... -exec sh -c 'blah "$ @" blah' sh {} + "(" shell trick ") để xử lý các vấn đề xung quanh việc đặt hàng đối số. Có một số ví dụ về điều này trong findutils ( thông tin) tài liệu, tìm kiếm "sh -c".
James Youngman

5

Xem xét mving thư mục cha thay vì các tệp:

mv /home/foo/bulk /home/foo2/bulk2 && mkdir /home/foo/bulk

(Nhưng nó có thể gây ra vấn đề nếu /home/foo/bulkphải tồn tại mọi lúc.)


1
Tôi sẽ thêm vào đó, chỉ trong trường hợp thư mục đích của bạn tồn tại, di chuyển các tệp trong thư mục đích đến thư mục nguồn của bạn (cái lớn) và đổi tên thư mục.
sbenitezb

Cảm ơn - gợi ý tuyệt vời. Trong trường hợp này, thư mục phải tồn tại ở mọi thời điểm. Ý tưởng tuyệt vời mặc dù.
Mike B

Tôi phải thừa nhận tôi không hiểu câu trả lời này là gì. Tại sao mkdir? Và những gì về dir đó "tồn tại ở mọi thời điểm" hay không? Tại sao điều này sẽ tăng tốc mọi thứ?
Monica Heddneck

Tôi biết nhận xét này là một năm tuổi, nhưng câu hỏi cuối cùng là năm tuổi, vì vậy tôi đoán rằng tôi cũng có thể trả lời ... Hai câu hỏi đầu tiên của bạn có tương quan. Các mkdirlà bởi vì toàn bộ thư mục và tất cả mọi thứ bên trong nó sẽ được di chuyển vào thư mục khác và không tồn tại lâu hơn trong thư mục cũ. Nó đảm bảo rằng thư mục cũ vẫn tồn tại. Tuy nhiên, điều này sẽ không đủ nếu có một dịch vụ liên tục chạy phụ thuộc vào thư mục đầu tiên luôn tồn tại, bởi vì nó được di chuyển và sau đó được tạo lại. Nó không làm bất cứ điều gì nhanh hơn, chỉ đơn giản hơn bằng cách cung cấp ít đối số hơn.
Lucas Leblanc

0

Chỉ để đa dạng, tôi thích sử dụng cpio cho một số trường hợp như thế này.

find tmp |cpio -v  -p --make-directories --sparse tmp2

1
Nếu nguồn và đích nằm trên cùng một hệ thống tệp thì cách tiếp cận này có thể rất không hiệu quả (sao chép không cần thiết). Ngoài ra nó luôn luôn tốt hơn để sử dụng -print0-0các tùy chọn.
pabouk

0

Với GNU mv:

find . -mindepth 1 -exec mv -t /tmp {} +

Trên các hệ thống như OS X không có mv -tnhưng có -print0xargs -0:

find . -mindepth 1 -print0|xargs -0 -I, mv , /tmp

Hoặc nếu tên tệp không chứa dấu cách, dấu ngoặc kép, dấu gạch chéo ngược hoặc dòng mới (với OS X's xargs) hoặc dấu ngoặc kép, dấu gạch chéo ngược hoặc dòng mới (với GNU xargs):

ls|xargs -I, mv , /tmp

-3

Trong một thời gian nhất định, hãy thử như sau:

find . -name "*" -type f -mtime +7 -exec mv -t /folder/to/transfer/files {} +
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.