so sánh 2 thư mục và sao chép sự khác biệt trong thư mục thứ 3


32

Chạy Ubuntu 12.04, tôi muốn so sánh 2 thư mục, giả sử thư mục1 / và thư mục2 / và sao chép bất kỳ tệp nào khác với thư mục3 /. Ngoài ra còn có các tệp lồng nhau, do đó, các thư mục con phù hợp cũng sẽ được sao chép

Có một lệnh duy nhất sẽ giúp tôi? Tôi có thể lấy danh sách đầy đủ các tệp đã thay đổi đang chạy:

rsync -rcnC --out-format="%f" folder1/ folder2/

Nhưng rsync dường như không có khả năng "xuất" các tệp này trên một thư mục đích khác. Tôi có thể chuyển danh sách sang cp hoặc một số chương trình khác để các tệp được sao chép trong khi các thư mục cũng được tạo không? Ví dụ, tôi đã thử

rsync -rcnC --out-format="%f" folder1/ folder2/ | xargs cp -t folder3/

nhưng điều đó cũng không bảo vệ các thư mục, nó chỉ đơn giản là sao chép tất cả các tệp trong thư mục3 /


Tôi có lẽ muốn sử dụng một số sự kết hợp của diff -qrawkđể xây dựng danh sách, sau đó rsync...
ewwhite

Làm cách nào để sử dụng rsync với danh sách?
periklis

Tôi sẽ chạy for-loop hoặc sử dụng rsync --include-from=FILEtùy chọn.
ewwhite

(đừng lười biếng ...) Nhưng giải pháp rsync dưới đây rất thanh lịch.
ewwhite

Câu trả lời:


38

Sử dụng --compare-mệnh.

Từ trang người đàn ông:

--compare-Dest = DIR - Tùy chọn này hướng dẫn rsync sử dụng DIR trên máy đích như một hệ thống phân cấp bổ sung để so sánh các tệp đích với việc thực hiện chuyển (nếu các tệp bị thiếu trong thư mục đích). Nếu một tệp được tìm thấy trong DIR giống hệt với tệp của người gửi, tệp sẽ KHÔNG được chuyển đến thư mục đích. Điều này hữu ích để tạo một bản sao lưu thưa thớt chỉ các tệp đã thay đổi từ bản sao lưu trước đó.

đầu tiên hãy kiểm tra cú pháp của bạn với --dry-run

rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/

Sau đó, một khi bạn hài lòng với đầu ra:

rsync -aHxv --progress  --compare-dest=folder2/ folder1/ folder3/

này liên kết có một lời giải thích tốt về --compare-dest phạm vi.


1
Cảm ơn vì điều này, tôi đã không hiểu lời giải thích của trang man về tham số này. Đối với bất kỳ ai quan tâm, tôi đã làm điều đó vớirsync -rcC --compare-dest=folder2/ folder1/ folder3/
periklis

lưu ý nhanh cho người dùng OsX. Tôi có rsync version 3.1.1 protocol version 31địa phương và rsync không hiểu ~/đường dẫn cho --compare-destparam.
Jevgeni Smirnov

4
Đối với tôi, --compare-destyêu cầu một con đường tuyệt đối.
palswim

Không làm việc cho tôi với các tùy chọn của tác giả hoặc OP. Tức là nó xuất ra fonts/Makefile.intập tin, giống hệt nhau trong cả hai folder2folder1dir.
Hi-Angel

3

Kịch bản nhỏ này sẽ hoạt động:

folder1="firsts_folder/"
folder2="second_folder/"
folder3="target_folder"
for x in `rsync -rcnC --out-format="%n"  $folder1 $folder2`
    do
        if [ -d "$folder1/$x" ]; then
            mkdir -p "$folder3/$x"
        else
            cp -frv $folder1/$x $folder3/$x
        fi
done

Nhưng tôi cũng nghĩ rằng phân tích cú pháp đầu ra của diff -qr sẽ là một giải pháp tốt hơn bởi vì nó cung cấp cho bạn đường dẫn và tên cho mỗi tệp một cách nhất quán.

CHỈNH SỬA

Đây sẽ là một lệnh, lệnh của bạn được sửa đổi một chút. Nhưng nó sẽ tạo ra folder1theo folder3. Và nó không hoạt động với các đường dẫn đầy đủ nhưng tập lệnh ở trên không hoạt động với các đường dẫn đầy đủ.

rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/

Tôi đã từng \"rsyncđể làm cho nó làm việc với các tập tin và thư mục có chứa khoảng trống. Đã thử nghiệm trên Ubuntu 10.04. Hy vọng nó giúp.


cảm ơn vì điều này, tôi đã hy vọng rằng một lệnh duy nhất sẽ tồn tại mặc dù
periklis

2
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/

Đó là hình thức đơn giản nhất tôi có thể nghĩ ra, nếu bạn sẵn sàng bước xuống folder1trước khi ra lệnh.

Đây là tùy chọn chậm hơn , nhưng tôi tin rằng nó đáp ứng yêu cầu của bạn và có thể được thực thi bằng tên thư mục không liên quan:

rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/

Tôi đã để lại rsynclệnh ban đầu của bạn , bởi vì bạn nói rằng nó đã đưa cho bạn danh sách tệp chính xác (và các tệp kiểm tra của tôi rõ ràng khác với lệnh của bạn, vì vậy tôi không thể nói chắc chắn rằng tôi sẽ nhận được danh sách tệp chính xác nếu tôi nhầm với nó).

grepđể xóa tên thư mục từ đầu ra của rsync.

Đầu ra của grepsau đó được chuyển sang rsyncsử dụng khác xargs. Trong thông số, folder1/./{}phần bổ sung ./được sử dụng để báo cho rsync để tạo các thư mục tương đối bắt đầu bằng ./{}, bỏ qua folder1/. Nói cách khác, nó tránh tạo ra folder3/folder1/.

Tôi chỉ có thể kiểm tra điều này trên CentOS 6.4, nhưng AFAIK nó sẽ hoạt động tương tự trong Ubuntu 12.04.

EDIT: Tôi nên lưu ý rằng câu trả lời của smithian chắc chắn là tốt hơn, nhưng tôi muốn thực hiện nó bằng rsynclệnh ban đầu của bạn một cách khéo léo vì nó mang lại cho bạn đầu ra mong muốn.

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.