rsync chỉ sao chép trên một số loại tệp nhất định bằng cách sử dụng tùy chọn include


110

Tôi sử dụng tập lệnh bash sau để chỉ sao chép các tệp có phần mở rộng nhất định (trong trường hợp này là * .sh), tuy nhiên nó vẫn sao chép tất cả các tệp. chuyện gì vậy?

từ = $ 1
thành = $ 2

rsync -zarv --include = "*. sh" $ từ $ đến

4
Mặc dù không nói đúng về liên quan, tôi khuyên bạn nên trích dẫn $ từ / $ đến. Không làm như vậy có thể mang lại cho bạn kết quả không mong muốn nếu các đối số vị trí 1/2 bao gồm dấu cách.
Kjetil Joergensen

bạn có hiểu tại sao lệnh của bạn không hoạt động không?
Charlie Parker

@CharlieParker: Bạn có phải sử dụng không rsync, điều này rất có thể đạt được với phần bên trong của shell?
Inian

Điều mà câu hỏi này và câu trả lời của nó còn thiếu là cách tạo lệnh nếu tôi có các thư mục đệ quy mà tôi chỉ muốn gửi một loại tệp. Có vẻ như nó chỉ làm điều đó cho thư mục đích ...
Charlie Parker

Câu trả lời:


198

Tôi nghĩ rằng --includenó được sử dụng để bao gồm một tập hợp con các tệp bị loại trừ bởi --exclude, thay vì chỉ bao gồm những tệp đó. Nói cách khác: bạn phải nghĩ đến nghĩa bao gồm không loại trừ .

Hãy thử thay thế:

rsync -zarv  --include "*/" --exclude="*" --include="*.sh" "$from" "$to"

Đối với rsync phiên bản 3.0.6 trở lên, thứ tự cần được sửa đổi như sau (xem nhận xét):

rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"

Thêm -mcờ sẽ tránh tạo cấu trúc thư mục trống trong đích. Đã thử nghiệm trong phiên bản 3.1.2.

Vì vậy, nếu chúng ta chỉ muốn các tệp * .sh, chúng ta phải loại trừ tất cả các tệp --exclude="*", bao gồm tất cả các thư mục --include="*/"và bao gồm tất cả các tệp * .sh --include="*.sh".

Bạn có thể tìm thấy một số ví dụ điển hình trong phần Bao gồm / Loại trừ Quy tắc mẫu của trang người đàn ông


10
Mặc dù nó sẽ cung cấp cho bạn tất cả các thư mục con, nhưng nếu có bất kỳ tệp .sh nào trong thư mục con mà bạn muốn rsync, rất có thể bạn sẽ muốn sử dụng --include = "* /".
Kjetil Joergensen

50
Tôi đã thử điều này trên rsync phiên bản 3.0.7, mà tôi đã nhận được từ lâu từ macports và nó không hoạt động với thứ tự bao gồm / loại trừ này. Đây là những gì tôi đã kết thúc với nó đã làm việc cho tôi (điều chỉnh cho OP) : rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to".
Bijou Trouvaille

3
Tôi đã thử với rsync 3.0.9 và nó không hoạt động. Bijou là đúng, thứ tự là không thích hợp (đầu tiên --include=\*.shsau đó --exclude=\*)
TrueY

3
Lưu ý rằng bạn luôn có thể nhấp vào chỉnh sửa và đề xuất chỉnh sửa để câu trả lời :)
Achal Dave

2
Nó không làm việc với đặt hàng lại bao gồm exludes /, nhưng nó hoạt động với thứ tự được đề xuất bởi Bijou Trouvaille
John Smith bắt buộc

56

Câu trả lời của @chepner sẽ sao chép tất cả các thư mục con bất kể thực tế là nó có chứa tệp hay không. Nếu bạn cần loại trừ các thư mục con không chứa tệp và vẫn giữ cấu trúc thư mục, hãy sử dụng

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"

1
Đây là một yêu cầu đối với tôi: "Nếu bạn cần loại trừ các thư mục con mà dont chứa các tập tin và vẫn giữ lại cấu trúc thư mục" +1
Juuso Ohtonen

1
Tôi không hiểu làm thế nào bạn biết thứ tự của - bao gồm là gì?
Charlie Parker

1
Làm thế nào để tạo lệnh nếu tôi có các thư mục đệ quy mà tôi chỉ muốn gửi một loại tệp. Có vẻ như nó chỉ làm điều đó cho thư mục đích.
Charlie Parker

15

Một bổ sung nữa: nếu bạn cần đồng bộ hóa các tệp bằng các phần mở rộng của nó chỉ trong một dir (không có đệ quy), bạn nên sử dụng cấu trúc như sau:

rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/

Hãy chú ý đến dấu chấm ở đầu tiên --include. --no-rkhông hoạt động trong xây dựng này.

BIÊN TẬP:

Cảm ơn gbyte.co vì nhận xét quý giá!


1
Làm thế nào bạn biết thứ tự của các lá cờ phải như thế nào và chúng cần bao gồm những gì?
Charlie Parker

1
@CharlieParker, bởi vì rsync sử dụng includevà các excludetùy chọn theo thứ tự mà chúng đã được chỉ định. Ngoài ra, nó dừng lại ở tùy chọn phù hợp đầu tiên. Vì vậy, nếu chúng ta chỉ định --exclude '*'ở vị trí đầu tiên trong ví dụ này, rsync sẽ không làm gì cả. Gặp người đàn ông để giải thích thêm.
Serge Roussak

bạn có thể giải thích cho tôi những gì mỗi lá cờ đang làm? Cờ đầu tiên -- include './' đang nói bao gồm mọi thứ trong đường dẫn thư mục nguồn? Sau đó, cái tiếp theo `--include '.ext' 'bao gồm tệp cụ thể trong đường dẫn nguồn được đặt tên .extvà sau đó loại trừ cho biết không gửi bất kỳ thứ gì khác --exclude '*'? Đúng không?
Charlie Parker

1
Làm thế nào để tạo lệnh nếu tôi có các thư mục đệ quy mà tôi chỉ muốn gửi một loại tệp. Có vẻ như nó chỉ làm điều đó cho thư mục đích.
Charlie Parker

1
Cảm ơn vì điều đó! Cần --include '*.ext'và không--include '.ext'
gbyte

13

Đây là phần quan trọng từ trang người đàn ông:

Khi danh sách các tệp / thư mục cần chuyển được tạo, rsync sẽ lần lượt kiểm tra từng tên được chuyển với danh sách các mẫu bao gồm / loại trừ và mẫu đối sánh đầu tiên được thực hiện: nếu đó là mẫu loại trừ thì tệp đó sẽ bỏ qua; nếu nó là một mẫu bao gồm thì tên tệp đó không bị bỏ qua; nếu không tìm thấy mẫu phù hợp, thì tên tệp không bị bỏ qua.

Tóm lại:

  • Không khớp với bất kỳ mẫu nào có nghĩa là một tệp sẽ được sao chép!
  • Thuật toán sẽ thoát khi bất kỳ mẫu nào khớp

Ngoài ra, một cái gì đó kết thúc bằng dấu gạch chéo là khớp với các thư mục (như find -type dsẽ).

Hãy tách câu trả lời này ra khỏi phần trên.

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"
  1. Đừng bỏ qua bất kỳ thư mục nào
  2. Đừng bỏ qua bất kỳ .shtệp nào
  3. Bỏ qua mọi thứ
  4. (Rõ ràng là không bỏ qua bất kỳ điều gì, nhưng quy tắc trên ngăn quy tắc mặc định không bao giờ xảy ra.)

Cuối cùng, --prune-empty-directoriesgiữ nguyên tắc đầu tiên không tạo các thư mục trống ở khắp nơi.


Cảm ơn bạn rất nhiều vì đã giải thích những gì đang xảy ra. Bây giờ có nhiều cơ hội tốt hơn là tôi sẽ không quên lệnh.
MohamedEzz

3
'' Thuật toán sẽ thoát khi bất kỳ mẫu nào khớp " - đây là chìa khóa và không có câu trả lời nào được xếp hạng cao hơn giải thích nó rõ ràng và chính xác như bạn đã làm ở đây. Tất nhiên đây trong trang người đàn ông nào đó, và nếu tôi 'd đọc kỹ toàn bộ, tôi đã thấy điều đó. Tuy nhiên, cảm ơn.
TheDudeAbides

0

Nếu ai đó tìm kiếm điều này… Tôi chỉ muốn rsync các tệp và thư mục cụ thể và đã quản lý để thực hiện điều đó bằng lệnh này: rsync --include-from=rsync-files

Với rsync-files:

my-dir/
my-file.txt

- /*

0

Đã viết chức năng tiện dụng này và đưa vào các tập lệnh bash của tôi hoặc ~/.bash_aliases. Đã thử nghiệm đồng bộ hóa cục bộ trên Linux với bash và awkđược cài đặt. Nó hoạt động

selrsync(){
# selective rsync to sync only certain filetypes;
# based on: https://stackoverflow.com/a/11111793/588867
# Example: selrsync 'tsv,csv' ./source ./target --dry-run
types="$1"; shift; #accepts comma separated list of types. Must be the first argument.
includes=$(echo $types| awk  -F',' \
    'BEGIN{OFS=" ";}
    {
    for (i = 1; i <= NF; i++ ) { if (length($i) > 0) $i="--include=*."$i; } print
    }')
restargs="$@"

echo Command: rsync -avz --prune-empty-dirs --include="*/" $includes --exclude="*" "$restargs"
eval rsync -avz --prune-empty-dirs --include="*/" "$includes" --exclude="*" $restargs
}

Avantages:

ngắn gọn, tiện dụng và có thể mở rộng khi muốn thêm nhiều đối số hơn (tức là --dry-run).

Thí dụ:

selrsync 'tsv,csv' ./source ./target --dry-run
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.