Cách nhanh nhất để di chuyển một triệu hình ảnh từ thư mục này sang thư mục khác trong Linux là gì?


14

Tôi có một triệu hình ảnh chiếm 30 GB dung lượng đĩa cần được chuyển từ thư mục cục bộ này sang thư mục cục bộ khác.

Điều gì sẽ là cách hiệu quả nhất để làm điều này? Sử dụng mv? Sử dụng cp? Sử dụng rsync? Thứ gì khác?

Tôi cần phải thực hiện những điều này:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

và di chuyển chúng đến đây:

/path/to/new/img/dir/

5
Tôi không nghĩ bạn có thể đánh bại mv, hiệu năng khôn ngoan, nếu cả thư mục nguồn và thư mục đích nằm trong cùng một hệ thống tệp.
Frédéric Hamidi

Câu trả lời:


26

rsync sẽ là một lựa chọn kém bởi vì nó thực hiện rất nhiều công việc của máy khách / máy chủ, chiếm các hệ thống từ xa cũng như cục bộ.

mvcó lẽ là sự lựa chọn tốt nhất Nếu có thể, bạn nên thử mv directory_old directory_newchứ không phải mv directory_old/* directory_new/. Bằng cách này, bạn di chuyển một thứ thay vì một triệu thứ.


6
+1 cho lời khuyên để di chuyển các thư mục thay vì các tệp.
Ex Umbris

4
Thêm vào đó, việc mở rộng ký tự đại diện có thể sẽ phá vỡ các đối số tối đa được hỗ trợ mvnếu chúng ta đang nói về hàng triệu người.
slhck

6
rsync xử lý chuyển trên phương tiện lưu trữ cục bộ tốt. Nó buộc những thứ như --whole-file (loại bỏ việc thực hiện thuật toán delta xfer) và ngăn chặn những thứ khác như - nén không phục vụ mục đích chuyển tiền cục bộ. Nếu các thư mục nằm trên các hệ thống tệp khác nhau, 'mv' sẽ không cung cấp bất kỳ loại hiệu suất nào. Nếu họ cư trú trên cùng một hệ thống tập tin, thì chỉ cần 'mv' các thư mục như những người này đã nói.
UtahJarhead

Nếu có nhiều hình ảnh, sử dụng ký tự đại diện shell đơn giản sẽ tràn dòng lệnh tối đa.
Raúl Salinas-Monteagudo

1
Di chuyển giữa các đĩa vẫn sẽ di chuyển tất cả dữ liệu. Trên cùng một đĩa, mvchỉ cần cập nhật thông tin inode để mv directory_old directory_newhoạt động nhanh hơnmv directory_old/* directory_new
Anshul

14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Điều này sẽ không tràn mở rộng đối số.
  • Bạn có thể chỉ định phần mở rộng tập tin, nếu bạn muốn. (-Tên ...)
  • find -print0với xargs -0cho phép bạn sử dụng khoảng trắng trong tên.
  • xargs -rsẽ không chạy mvtrừ khi có gì đó để di chuyển. ( mvsẽ khiếu nại nếu không có tệp nguồn nào được đưa ra).
  • Cú pháp mv -tcho phép bạn chỉ định đích đầu tiên và sau đó là các tệp nguồn, cần thiết bởi xargs.
  • Di chuyển toàn bộ thư mục tất nhiên là nhanh hơn nhiều, vì nó diễn ra trong thời gian không đổi bất kể số lượng tệp có trong đó, nhưng:
    • thư mục nguồn sẽ biến mất trong một phần nhỏ thời gian và nó có thể tạo ra vấn đề cho bạn;
    • nếu quá trình đang sử dụng thư mục hiện tại làm thư mục đầu ra (ngược lại luôn luôn đề cập đến một đường dẫn đầy đủ từ một vị trí không di chuyển), bạn sẽ phải khởi chạy lại nó. (giống như bạn làm với vòng quay log ).

Nhân tiện, tôi sẽ tự hỏi mình có thực sự phải di chuyển một lượng lớn tệp như vậy cùng một lúc không. Xử lý hàng loạt được đánh giá cao. Tôi cố gắng không tích lũy khối lượng công việc khổng lồ nếu tôi có thể xử lý mọi thứ tại thời điểm chúng được tạo ra.


Điều này hoạt động đủ tốt để di chuyển các tệp trên các hệ thống tệp trên cùng một máy chủ. Đủ để tôi không bận tâm tìm kiếm giải pháp trong rsync. Chắc chắn phải mất một hoặc hai giờ, nhưng nó hoạt động. Một điều cần lưu ý, nếu bạn đưa ra một tên thư mục thay vì "." - hãy chắc chắn sử dụng dấu gạch chéo trong lệnh find, nếu không thư mục sẽ được tạo lại ở đích của lệnh mv.
Speeddymon

7

Nếu hai thư mục nằm trên cùng một hệ thống tập tin, hãy sử dụng mvtrên TRỰC TIẾP chứ không phải nội dung của thư mục.

Nếu chúng nằm trên hai hệ thống tệp khác nhau, hãy sử dụng rsync:

rsync -av /source/directory/ /destination

Chú ý dấu vết /trên nguồn. Điều này có nghĩa là nó sẽ sao chép NỘI DUNG của thư mục chứ không phải chính thư mục đó. Nếu bạn rời /khỏi, nó vẫn sẽ sao chép các tập tin nhưng chúng sẽ nằm trong một thư mục có tên /destination/directory. Với /, các tệp sẽ nằm trong/destination

rsyncsẽ duy trì quyền sở hữu tệp nếu bạn chạy nó dưới quyền root hoặc nếu các tệp thuộc sở hữu của bạn. Nó cũng sẽ duy trì các mtimetập tin cá nhân.


2
Để sao chép một thư mục lớn từ một ổ cứng sang một ổ cứng khác, rsyncdường như chạy các vòng tròn xung quanh mv. Cảm ơn vì tiền hỗ trợ!
Leo-the-manic

2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

Khi bạn sử dụng 'cp', mỗi tệp sẽ thực hiện mở-đọc-đóng-mở-ghi-đóng. Tar sử dụng các quy trình khác nhau để đọc và viết cũng như nhiều bước để hoạt động trên nhiều tệp cùng một lúc. Ngay cả trên một hộp CPU, các ứng dụng đa luồng cũng nhanh hơn.


2
Trong khi điều này có thể trả lời câu hỏi, nó sẽ là một câu trả lời tốt hơn nếu bạn có thể cung cấp một số lời giải thích tại sao nó làm như vậy.
DavidPostill

1
Nếu chúng ở trong máy cục bộ, rất có thể chúng nằm trong cùng một hệ thống tệp. Bằng cách sử dụng, tar c | tar xbạn nhận được một chi phí là O (Total_size) thay vì O (file_count).
Raúl Salinas-Monteagudo

1

Vì cả thư mục_old và thư mục_new đều nằm trên cùng một hệ thống tệp, bạn có thể sử dụng cp -lthay vì mvdưới dạng tùy chọn. cp -lsẽ tạo ra một liên kết cứng đến các tập tin gốc. Khi bạn hoàn thành với 'di chuyển' và bạn hài lòng với kết quả thì bạn có thể xóa các tệp này khỏi thư mục_old. về tốc độ, nó sẽ giống như 'mv' khi bạn lần đầu tiên tạo các liên kết và sau đó bạn xóa các liên kết ban đầu. Nhưng phương pháp này cho phép bạn bắt đầu lại từ đầu nếu điều này có ý nghĩa


0

Nó phụ thuộc (tm). Nếu hệ thống tập tin của bạn là copy-on-write, thì sao chép ( cphoặc rsync, chẳng hạn) sẽ tương đương với một động thái. Nhưng đối với hầu hết các trường hợp phổ biến, move ( mv) sẽ là nhanh nhất, vì nó có thể chỉ cần chuyển xung quanh các phần dữ liệu mô tả nơi đặt tệp (lưu ý: điều này được đơn giản hóa quá mức).

Vì vậy, trên cài đặt Linux trung bình của bạn, tôi sẽ đi mv.

EDIT: @ Frédéric Hamidi có một điểm tốt trong các nhận xét: Điều này chỉ hợp lệ nếu cả hai đều trên cùng một hệ thống tệp và đĩa. Nếu không, dữ liệu sẽ được sao chép.


0

Để sao chép ít nhất ~ 10k tệp (không có thư mục), cp đã khiếu nại:

không thể thực thi / bin / cp: Danh sách đối số quá dài

Tùy chọn tốt nhất là Rsync:

mục tiêu nguồn rsync

Và nó đã được thực hiện rất nhanh!


0

Nếu bạn có không gian trống, hãy lưu trữ chúng vào một tệp .tar (không nén được nhanh hơn) và sau đó di chuyển tệp đó qua và hủy lưu trữ tệp đó.


0

Bản chất của điểm đến sẽ xác định cách hiệu quả nhất để thực hiện nhiệm vụ này. Giả sử bạn đang ở trên một hệ thống cục bộ, bạn PWDđang /ở ngay bây giờ. và /achứa hàng triệu hình ảnh. Nhiệm vụ của chúng tôi là di chuyển tất cả các hình ảnh sang /b, trong khi duy trì tất cả cấu trúc thư mục con. Cũng giả sử /a/blà điểm gắn kết cho hai phân vùng khác nhau, mỗi phân vùng trên một đĩa được kết nối cục bộ. Chúng tôi muốn thực hiện nhiệm vụ này với một tarpipe. Điều này có thể mất một thời gian, do đó hãy chắc chắn rằng bạn đang sử dụng screen, tmuxhoặc bạn thực hiện điều này như một quá trình nền.

tar -C /a -cf . | tar -C /b -xf -

Điều đó sẽ sao chép tất cả các file và thư mục trong /ađể /b, vì vậy bây giờ bạn sẽ cần phải dọn dẹp /amột khi bạn xác nhận nó hoàn thành mà không có lỗi.

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.