Làm thế nào để rsync chỉ một danh sách các tệp cụ thể?


95

Tôi có khoảng hơn 50 tệp trong các thư mục con khác nhau mà tôi muốn đẩy đến một máy chủ từ xa. Tôi đã nghĩ rằng rsync sẽ có thể thực hiện việc này cho tôi bằng cách sử dụng tùy chọn - bao gồm từ. Nếu không có tùy chọn --exclude = "*", tất cả các tệp trong thư mục đang được đồng bộ hóa, với tùy chọn này, không có tệp nào.

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

Tôi đang chạy nó ban đầu là khô và 0.0.0.0 rõ ràng được thay thế bằng IP của máy chủ từ xa. Nội dung của rsync_include.txt là danh sách các đường dẫn tương đối được phân tách bằng dòng mới đến các tệp tôi muốn tải lên.

Có cách nào tốt hơn để làm điều này đang trốn thoát tôi vào sáng thứ Hai không?

Câu trả lời:


4

Chỉnh sửa: Câu trả lời của Josip Rodin dưới đây là tốt hơn. Hãy sử dụng cái đó!

Bạn có thể có thời gian dễ dàng hơn, nếu bạn đang tìm kiếm một danh sách các tệp cụ thể, hãy đặt chúng trực tiếp trên dòng lệnh thay vào đó:

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

Tuy nhiên, điều này giả định rằng danh sách của bạn không quá dài nên độ dài dòng lệnh sẽ là một vấn đề và rsync_include.txttệp chỉ chứa các đường dẫn thực (tức là không có chú thích và không có regexps).


9
Thật không may, điều này không hoạt động với một danh sách lớn hoặc với các tệp có khoảng trắng trong tên.
Chế độ Wes

3
[Danh sách đối số quá dài]
Dankó Dávid

Theo mặc định, xargs nối các đối số từ stdin vào cuối dòng lệnh. Điều đó không hoạt động vì rsync cần đối số cuối cùng làm đích. Một số phiên bản của xargs có thể tùy chọn chèn các đối số vào giữa dòng lệnh. Điều đó sẽ hoạt động miễn là bạn không bận tâm rằng nó có thể chạy rsync nhiều lần khi danh sách tệp dài. Trong mọi trường hợp, rsync --files-fromcó lẽ là một giải pháp dễ dàng hơn và đáng tin cậy hơn :)
Lassi

Wes Hardaker: Chỉnh sửa và tham chiếu đến "câu trả lời của Josip Rodin" có thực sự tham khảo câu trả lời @atp mà Rodin đã chỉnh sửa không?
Seamus

234

Có một lá cờ --files-fromthực hiện chính xác những gì bạn muốn. Từ man rsync:

--files-from=FILE

Sử dụng tùy chọn này cho phép bạn chỉ định danh sách chính xác các tệp cần chuyển (như được đọc từ FILE được chỉ định hoặc - đối với đầu vào chuẩn). Nó cũng điều chỉnh hành vi mặc định của rsync để chỉ chuyển các tệp và thư mục được chỉ định dễ dàng hơn:

  • Tùy chọn --relative (-R) được ngụ ý, nó bảo toàn thông tin đường dẫn được chỉ định cho từng mục trong tệp (sử dụng --no-relative hoặc --no-R nếu bạn muốn tắt nó).

  • Tùy chọn --dirs (-d) được ngụ ý, sẽ tạo các thư mục được chỉ định trong danh sách trên đích thay vì bỏ qua chúng một cách ồn ào (sử dụng --no-dirs hoặc --no-d nếu bạn muốn tắt điều đó).

  • Hành vi của tùy chọn --archive (-a) không ngụ ý --recursive (-r), vì vậy hãy chỉ định nó một cách rõ ràng, nếu bạn muốn.

  • Những tác dụng phụ này thay đổi trạng thái mặc định của rsync, vì vậy vị trí của tùy chọn --files-from trên dòng lệnh không liên quan đến cách các tùy chọn khác được phân tích cú pháp (ví dụ -a hoạt động giống nhau trước hoặc sau --files- từ, cũng như vậy --no-R và tất cả các tùy chọn khác).

Các tên tệp được đọc từ FILE đều liên quan đến dir nguồn - bất kỳ dấu gạch chéo nào ở đầu đều bị xóa và không có tham chiếu ".." nào được phép cao hơn dir nguồn. Ví dụ: lấy lệnh này:

rsync -a --files-from=/tmp/foo /usr remote:/backup

Nếu / tmp / foo chứa chuỗi "bin" (hoặc thậm chí "/ bin"), thư mục / usr / bin sẽ được tạo dưới dạng / backup / bin trên máy chủ từ xa. Nếu nó chứa "bin /" (lưu ý dấu gạch chéo ở cuối), nội dung ngay lập tức của thư mục cũng sẽ được gửi (mà không cần phải đề cập rõ ràng trong tệp - điều này bắt đầu trong phiên bản 2.6.4). Trong cả hai trường hợp, nếu tùy chọn -r được kích hoạt, toàn bộ hệ thống phân cấp của dir đó cũng sẽ được chuyển (hãy nhớ rằng -r cần được chỉ định rõ ràng bằng --files-from, vì nó không được ngụ ý bởi -a). Cũng lưu ý rằng tác dụng của tùy chọn tương đối (được bật theo mặc định) là chỉ sao chép thông tin đường dẫn được đọc từ tệp - nó không buộc sao chép đường dẫn nguồn-spec (/ usr trong trường hợp này) .

Ngoài ra, tệp --files-from có ​​thể được đọc từ máy chủ từ xa thay vì máy chủ cục bộ nếu bạn chỉ định "máy chủ:" ở phía trước tệp (máy chủ phải khớp với một đầu của quá trình truyền). Tóm lại, bạn có thể chỉ định một tiền tố là ":" có nghĩa là "sử dụng kết thúc chuyển từ xa". Ví dụ:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

Thao tác này sẽ sao chép tất cả các tệp được chỉ định trong tệp / path / file-list nằm trên máy chủ lưu trữ "src" từ xa.

Nếu các tùy chọn --iconv và --protect-args được chỉ định và tên tệp --files-from đang được gửi từ máy chủ này sang máy chủ khác, thì tên tệp sẽ được dịch từ bộ ký tự của máy chủ gửi sang bộ mã của máy chủ nhận.

LƯU Ý: sắp xếp danh sách các tệp trong đầu vào --files-from giúp rsync hiệu quả hơn, vì nó sẽ tránh việc truy cập lại các phần tử đường dẫn được chia sẻ giữa các mục liền kề. Nếu đầu vào không được sắp xếp, một số phần tử đường dẫn (thư mục ngụ ý) có thể bị quét nhiều lần và rsync cuối cùng sẽ hủy trùng lặp chúng sau khi chúng được chuyển thành phần tử danh sách tệp.


23
Lưu ý rằng bạn vẫn phải chỉ định thư mục chứa các tệp được liệt kê, ví dụ: rsync -av --files-from=file-list . target/để sao chép tệp từ dir hiện tại.
Nicolas Mattia

7
Vâng, và nhắc lại: The filenames that are read from the FILE are all relative to the source dir.
atp

Ah, bỏ lỡ điều đó, xin lỗi!
Nicolas Mattia

1
nếu tệp files-from có ​​bất kỳ thứ gì bắt đầu bằng ..rsync dường như sẽ bỏ qua việc ..tạo cho tôi một lỗi như rsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory(trong trường hợp này là chạy từ dir "test" và cố gắng chỉ định "../subdir/test.txt" tồn tại.
Michael

Có thể --files-fromlập luận được kết hợp với một danh sách rõ ràng của bao gồm và không bao gồm, và các tập tin từ danh sách sẽ thêm với --files-fromquy tắc ghi đè hiện loại trừ, như vậy mà họ được đưa vào nếu chúng xuất hiện trong các tập tin?
highsciguy 14/03/18

13

--files-from=tham số cần dấu gạch chéo nếu bạn muốn giữ nguyên đường dẫn tuyệt đối. Vì vậy, lệnh của bạn sẽ trở thành một cái gì đó như sau:

rsync -av --files-from=/path/to/file / /tmp/

Điều này có thể được thực hiện giống như có một số lượng lớn các tệp và bạn muốn sao chép tất cả các tệp vào đường dẫn x. Vì vậy, bạn sẽ tìm thấy các tệp và chuyển đầu ra cho một tệp như dưới đây:

find /var/* -name *.log > file

9

Đối với hồ sơ, không có câu trả lời nào ở trên hữu ích ngoại trừ một câu trả lời. Tóm lại, bạn có thể thực hiện thao tác sao lưu bằng --files-from=cách sử dụng:

 rsync -aSvuc `cat rsync-src-files` / mnt / d / rsync_test /

HOẶC LÀ

rsync -aSvuc --recursive --files-from = rsync-src-files. / mnt / d / rsync_test /

Lệnh trước đây là tự giải thích, bên cạnh nội dung của tệp rsync-src-filesmà tôi sẽ trình bày chi tiết bên dưới. Bây giờ, nếu bạn muốn sử dụng phiên bản sau, bạn cần ghi nhớ bốn lưu ý sau:

  1. Lưu ý một người cần chỉ định cả --files-fromvà thư mục nguồn
  2. Người ta cần xác định rõ ràng --recursive.
  3. Tệp rsync-src-fileslà tệp do người dùng tạo và nó được đặt trong thư mục src cho thử nghiệm này
  4. rsyn-src-fileschứa các tệp và thư mục để sao chép và chúng được đưa vào thư mục nguồn. QUAN TRỌNG: Đảm bảo không có khoảng trắng ở cuối hoặc dòng trống trong tệp. Trong ví dụ dưới đây, chỉ có hai dòng, không phải ba (tình cờ hình dung ra). Nội dung của rsynch-src-fileslà:

folderName1
folderName2


3

Tôi đã nhận nhiệm vụ tương tự: để rsync tất cả các tệp được sửa đổi sau ngày nhất định, nhưng loại trừ một số thư mục. Rất khó để xây dựng một kiểu lót tất cả trong một, vì vậy tôi đã giải quyết vấn đề thành các phần nhỏ hơn. Giải pháp cuối cùng:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

Đầu tiên tôi sử dụng find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". Tôi đã cố gắng thêm regexvào finddòng để loại trừ các mẫu tên, tuy nhiên hương vị của các đường nối Linux (Mint) của tôi không hiểu phủ định regex trong find. Số lượng hương vị regex đã thử - không hoạt động như mong muốn. Vì vậy, tôi kết thúc với egrep -v- tùy chọn loại trừ mẫu một cách dễ dàng. Của tôi rsynckhông sao chép các thư mục như /.cache hoặc /.config cộng với một số khác mà tôi đặt tên rõ ràng.


1
Tôi tin rằng bạn có thể sử dụng thay thế tiến trình để tắt chức năng này thành một bashone-liner:rsync -v --files-from=<(find ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | grep -Ev "/\..|Downloads|FOO") ~/sourceDIR /Destination
PHK

2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

Cú pháp: rsync <file_/_folder_list> <source> <target>

Tên thư mục (ở đây, CÓ dấu /; ví dụ Cancer - Evolution/:) nằm trong tệp danh sách thư mục (ví dụ: cm_folder_list_test):

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

Nếu bạn không bao gồm các /thư mục theo sau đó , các thư mục đích rsync'd sẽ được tạo, nhưng trống.

Các tên thư mục đó được nối vào phần còn lại của đường dẫn ( /home/victoria/Mail/2_RESEARCH - NEWS), do đó cung cấp đường dẫn thư mục hoàn chỉnh tới rsync; ví dụ: /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/.

Lưu ý rằng bạn cũng cần sử dụng --files-from=..., KHÔNG --include-from=...

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(Trong tập lệnh BASH của tôi, tôi đã định nghĩa biến $INnhư sau.)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

Các tùy chọn rsync được sử dụng:

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (/server/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...

1

Câu trả lời này không phải là câu trả lời trực tiếp cho câu hỏi. Nhưng nó sẽ giúp bạn tìm ra giải pháp nào phù hợp nhất cho vấn đề của bạn.

Khi phân tích vấn đề, bạn nên kích hoạt tùy chọn gỡ lỗi -vv

Sau đó, rsync sẽ xuất ra tệp nào được bao gồm hoặc loại trừ theo mẫu nào:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *

0

Không có câu trả lời nào trong số này phù hợp với tôi, khi tất cả những gì tôi có là một danh sách các thư mục . Sau đó, tôi tình cờ tìm ra giải pháp! Bạn phải thêm -rvào --files-from-asẽ không được đệ quy trong trường hợp này (ai biết ?!).

rsync -aruRP --files-from=directory.list . ../new/location

Nếu bạn liệt kê “dir” trong tệp thì bạn cần chỉ định -r / —recursive; nếu bạn liệt kê "dir /" thì bạn không.
lbutlr
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.