Bagaimana cara rsync hanya untuk daftar file tertentu?

95

Saya memiliki sekitar 50 atau lebih file dalam berbagai sub-direktori yang ingin saya masukkan ke server jauh. Saya pikir rsync akan dapat melakukan ini untuk saya menggunakan opsi --include-from. Tanpa opsi --exclude = "*", semua file dalam direktori sedang diselaraskan, dengan opsi tersebut, tidak ada file.

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ [email protected]:/var/www/ --dry-run

Saya menjalankannya sebagai kering pada awalnya dan 0.0.0.0 jelas diganti dengan IP dari server jarak jauh. Isi rsync_include.txt adalah baris baru yang dipisahkan dari daftar jalur relatif ke file yang ingin saya unggah.

Adakah cara yang lebih baik untuk melakukan ini dengan melarikan diri dari saya pada Senin pagi?

Dan Steele
sumber

Jawaban:

4

Edit: Jawaban Josip Rodin di bawah ini lebih baik. Silakan gunakan yang itu!

Anda mungkin memiliki waktu yang lebih mudah, jika Anda mencari daftar file tertentu, letakkan langsung di baris perintah sebagai gantinya:

# rsync -avP -e ssh `cat deploy/rsync_include.txt` [email protected]:/var/www/

Namun demikian, ini mengasumsikan bahwa daftar Anda tidak terlalu panjang sehingga panjang baris perintah akan menjadi masalah dan bahwa rsync_include.txtfile tersebut hanya berisi jalur nyata (yaitu tidak ada komentar, dan tidak ada ekspresi reguler).

Wes Hardaker
sumber
9
Sayangnya, ini tidak berfungsi dengan daftar besar atau dengan file dengan spasi di namanya.
Wes Modes
3
[Daftar argumen terlalu panjang]
Dankó Dávid
Secara default, xargs menambahkan argumen dari stdin ke akhir baris perintah. Itu tidak berfungsi karena rsync membutuhkan argumen terakhir untuk menjadi tujuan. Beberapa versi xargs secara opsional dapat memasukkan argumen ke tengah baris perintah sebagai gantinya. Itu seharusnya bekerja selama Anda tidak keberatan itu mungkin menjalankan rsync lebih dari sekali ketika daftar file panjang. Bagaimanapun, rsync --files-fromini mungkin merupakan solusi yang lebih mudah dan lebih dapat diandalkan :)
Lassi
Wes Hardaker: Apakah Edit & referensi Anda ke "jawaban Josip Rodin" sebenarnya mengacu pada jawaban @atp yang diedit Rodin?
Seamus
234

Ada bendera --files-fromyang melakukan apa yang Anda inginkan. Dari man rsync:

--files-from=FILE

Menggunakan opsi ini memungkinkan Anda menentukan daftar file yang akan ditransfer (seperti yang dibaca dari FILE yang ditentukan atau - untuk input standar). Ini juga mengubah perilaku default rsync untuk membuat transfer file dan direktori yang ditentukan lebih mudah:

  • Opsi --relative (-R) tersirat, yang mempertahankan informasi jalur yang ditentukan untuk setiap item dalam file (gunakan --no-relative atau --no-R jika Anda ingin mematikannya).

  • Opsi --dirs (-d) tersirat, yang akan membuat direktori yang ditentukan dalam daftar pada tujuan daripada melewatinya dengan ribut (gunakan --no-dirs atau --no-d jika Anda ingin mematikannya).

  • Perilaku opsi --archive (-a) tidak menyiratkan --recursive (-r), jadi tentukan secara eksplisit, jika Anda menginginkannya.

  • Efek samping ini mengubah status default rsync, sehingga posisi opsi --files-from pada baris perintah tidak ada hubungannya dengan bagaimana opsi lain diurai (misalnya -a bekerja sama sebelum atau sesudah --files- dari, seperti halnya --no-R dan semua opsi lainnya).

Nama file yang dibaca dari FILE semuanya relatif terhadap direktori sumber - setiap garis miring di awal akan dihapus dan tidak ada referensi ".." yang diizinkan melebihi direktori sumber. Misalnya, ambil perintah ini:

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

Jika / tmp / foo berisi string "bin" (atau bahkan "/ bin"), direktori / usr / bin akan dibuat sebagai / backup / bin pada host jarak jauh. Jika itu berisi "bin /" (perhatikan garis miring), isi langsung dari direktori juga akan dikirim (tanpa perlu disebutkan secara eksplisit dalam file - ini dimulai pada versi 2.6.4). Dalam kedua kasus, jika opsi -r diaktifkan, seluruh hierarki dir itu juga akan ditransfer (perlu diingat bahwa -r perlu dispesifikasikan secara eksplisit dengan --files-from, karena tidak tersirat oleh -a). Perhatikan juga bahwa efek dari (diaktifkan secara default) - opsi relatif adalah menduplikasi hanya info jalur yang dibaca dari file - itu tidak memaksa duplikasi jalur spesifikasi sumber (/ usr dalam kasus ini) .

Selain itu, file --files-from dapat dibaca dari host jarak jauh daripada host lokal jika Anda menetapkan "host:" di depan file (host harus cocok dengan salah satu ujung transfer). Sebagai jalan pintas, Anda dapat menentukan hanya awalan ":" yang berarti "menggunakan ujung transfer yang jauh". Sebagai contoh:

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

Ini akan menyalin semua file yang ditentukan dalam file / path / file-list yang terletak di host "src" remote.

Jika opsi --iconv dan --protect-args ditentukan dan nama file --files-from dikirim dari satu host ke host lain, nama file akan diterjemahkan dari charset host pengirim ke charset host penerima.

CATATAN: menyortir daftar file dalam masukan --files-from membantu rsync menjadi lebih efisien, karena ini akan menghindari kunjungan ulang elemen jalur yang dibagi antara entri yang berdekatan. Jika input tidak diurutkan, beberapa elemen path (direktori tersirat) mungkin akan dipindai beberapa kali, dan rsync pada akhirnya akan membatalkan duplikatnya setelah diubah menjadi elemen daftar file.

atp
sumber
23
Perhatikan bahwa Anda masih harus menentukan direktori tempat file yang terdaftar berada, misalnya: rsync -av --files-from=file-list . target/untuk menyalin file dari direktori saat ini.
Nicolas Mattia
7
Ya, dan menegaskan kembali: The filenames that are read from the FILE are all relative to the source dir.
ATP
Ah, ketinggalan itu, maaf!
Nicolas Mattia
1
jika file-dari file memiliki sesuatu yang dimulai dengan ..rsync tampaknya mengabaikan ..memberi saya kesalahan seperti rsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory(dalam hal ini menjalankan dari "test" dir dan mencoba untuk menentukan "../subdir/test.txt" yang memang ada.
Michael
Dapatkah --files-fromargumen digabungkan dengan daftar eksplisit yang disertakan dan dikecualikan, dan akankah file dari daftar ditambahkan dengan --files-frommenimpa aturan pengecualian yang ada, sehingga akan disertakan jika muncul di file?
highsciguy
13

--files-from=parameter perlu garis miring jika Anda ingin jalur absolut tetap utuh. Jadi perintah Anda akan menjadi seperti di bawah ini:

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

Ini bisa dilakukan seperti ada banyak file dan Anda ingin menyalin semua file ke x path. Jadi Anda akan menemukan file dan membuang output ke file seperti di bawah ini:

find /var/* -name *.log > file
Waqas Khan
sumber
9

Sebagai catatan, tidak ada jawaban di atas yang membantu kecuali satu. Untuk meringkas, Anda dapat melakukan operasi pencadangan --files-from=dengan menggunakan:

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

ATAU

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

Perintah sebelumnya sudah cukup jelas, di samping konten file rsync-src-filesyang akan saya uraikan di bawah. Sekarang, jika Anda ingin menggunakan versi terakhir, Anda perlu mengingat empat komentar berikut:

  1. Perhatikan satu kebutuhan untuk menentukan keduanya --files-fromdan direktori sumber
  2. Seseorang perlu menentukan dengan jelas --recursive.
  3. File tersebut rsync-src-filesadalah file yang dibuat oleh pengguna dan ditempatkan dalam direktori src untuk pengujian ini
  4. The rsyn-src-filesberisi file dan folder untuk menyalin dan mereka dibawa relatif ke direktori source. PENTING: Pastikan tidak ada spasi atau baris kosong di file. Pada contoh di bawah, hanya ada dua garis, bukan tiga (Gambarkan secara kebetulan). Isi dari rsynch-src-filesadalah:

folderName1
folderName2

KF
sumber
3

Saya mendapat tugas serupa: untuk rsync semua file diubah setelah tanggal tertentu, tetapi tidak termasuk beberapa direktori. Sulit untuk membuat gaya satu liner all-in-one, jadi saya menyelami masalah menjadi bagian-bagian yang lebih kecil. Solusi akhir:

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

Pertama saya gunakan find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". Saya mencoba menambahkan regexke findbaris untuk mengecualikan pola nama, namun rasa Linux (Mint) saya tidak mengerti meniadakan regex di find. Mencoba jumlah rasa regex - tidak berfungsi seperti yang diinginkan. Jadi saya berakhir dengan egrep -v- opsi yang mengecualikan pola dengan cara mudah. Saya rsynctidak menyalin direktori seperti /.cache atau /.config ditambah beberapa saya lainnya secara eksplisit bernama.

sopel
sumber
1
Saya yakin Anda dapat menggunakan proses substitusi untuk mengubahnya menjadi bashsatu baris: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
  ...

Sintaksis: rsync <file_/_folder_list> <source> <target>

Nama folder (di sini, DENGAN tambahan /; misalnya Cancer - Evolution/) ada dalam file daftar folder (misalnya: 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/

Jika Anda tidak menyertakan trailing tersebut /, folder target rsync akan dibuat, tetapi kosong.

Nama folder tersebut ditambahkan ke path lainnya ( /home/victoria/Mail/2_RESEARCH - NEWS), sehingga menyediakan path folder lengkap ke rsync; mis /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/. : .

Perhatikan bahwa Anda juga perlu menggunakan --files-from=..., BUKAN --include-from=...

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

(Dalam skrip BASH saya, saya mendefinisikan variabel $INsebagai berikut.)

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

opsi rsync digunakan:

 -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).  ...
Victoria Stuart
sumber
1

Jawaban ini bukanlah jawaban langsung untuk pertanyaan tersebut. Tetapi itu akan membantu Anda menemukan solusi mana yang paling cocok untuk masalah Anda.

Saat menganalisis masalah, Anda harus mengaktifkan opsi debug -vv

Kemudian rsync akan menampilkan file mana yang disertakan atau dikecualikan dengan pola mana:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *
Matthias M
sumber
0

Tak satu pun dari jawaban ini berhasil untuk saya, ketika yang saya miliki hanyalah daftar direktori . Kemudian saya menemukan solusinya! Anda harus menambahkan -rke --files-fromkarena -atidak akan rekursif dalam skenario ini (yang tahu ?!).

rsync -aruRP --files-from=directory.list . ../new/location
Theodore R. Smith
sumber
Jika Anda mencantumkan "dir" dalam file tersebut maka Anda perlu menentukan -r / —recursive; jika Anda mencantumkan “dir /“ Anda tidak.
lbutlr