rsync dahil etme seçeneğini kullanarak yalnızca belirli dosya türlerini kopyalayın


110

Aşağıdaki bash komut dosyasını yalnızca belirli uzantılara sahip dosyaları (bu durumda * .sh) kopyalamak için kullanıyorum, ancak yine de tüm dosyaların üzerine kopyalar. Sorun nedir?

başlangıç ​​= 1 $
to = 2 $

rsync -zarv --include = "*. sh" $ $ 'dan

4
Kesinlikle ilgili olmasa da, $ 'dan / $' dan alıntı yapmanızı öneririm. Konumsal argümanlar 1/2 boşluklar içeriyorsa, bunu yapmamak size beklenmedik sonuçlar verebilir.
Kjetil Joergensen

emrinizin neden işe yaramayacağını anladınız mı?
Charlie Parker

@CharlieParker: Kullanmak zorunda mısınız rsync, bu kabuk iç kısımları ile çok iyi bir şekilde başarılabilir mi?
Inian

Bu sorunun ve yanıtlarının da eksik olduğu şey, yalnızca bir tür dosya göndermek istediğim özyinelemeli dizinlerim varsa, komutu nasıl oluşturacağımdır. ... bu sadece hedef dizinin yapar görünüyor
Charlie Parker'a

Yanıtlar:


200

Sanırım --include, --excludeyalnızca bu dosyaları dahil etmek yerine, tarafından hariç tutulan bir dosya alt kümesini dahil etmek için kullanılır . Başka bir deyişle: anlam dahil etme, hariç tutma hakkında düşünmeniz gerekir .

Bunun yerine deneyin:

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

Rsync sürüm 3.0.6 veya üstü için, sıranın aşağıdaki gibi değiştirilmesi gerekir (yorumlara bakın):

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

-mBayrağın eklenmesi, hedefte boş dizin yapıları oluşturmaktan kaçınacaktır. 3.1.2 sürümünde test edilmiştir.

Dolayısıyla, yalnızca * .sh dosyalarını istiyorsak --exclude="*", tüm dosyaları hariç tutmalı , tüm dizinleri --include="*/"içermeli ve tüm * .sh dosyalarını eklemeliyiz --include="*.sh".

Bölümünde bazı iyi örnekler bulabilirsiniz / içer Desen Kuralları dışla arasında adam sayfası


10
Size tüm alt dizinleri getirecek olsa da, alt dizinlerde rsync yapmak istediğiniz herhangi bir .sh dosyası varsa, muhtemelen --include = "* /" kullanmak isteyeceksiniz.
Kjetil Joergensen

50
Bunu, uzun zaman önce macports'tan aldığım rsync sürüm 3.0.7'de denedim ve bu dahil etme / dışlama sıralamasıyla çalışmadı. Bu benim (OP için uyarlanmış) benim için çalıştı ile sona erdi budur: rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to".
Bijou Trouvaille

3
Rsync 3.0.9 ile denedim ve işe yaramadı. Bijou haklı, sıralama uygun değil (önce --include=\*.shsonra --exclude=\*)
TrueY

3
Her zaman düzenle'yi tıklayabileceğinizi ve yanıta bir düzenleme önerebileceğinizi unutmayın :)
Achal Dave

2
Dahil etme / hariç tutma siparişinizle çalışmaz, ancak Bijou Trouvaille tarafından önerilen siparişle çalışır
John Smith İsteğe bağlı

57

@Chepner tarafından verilen yanıt, dosyayı içerip içermediğine bakılmaksızın tüm alt dizinleri kopyalayacaktır. Dosyayı içermeyen alt dizinleri dışarıda bırakmanız ve yine de dizin yapısını korumanız gerekiyorsa, şunu kullanın:

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

1
Bu benim için bir gereklilikti: "Dosyayı içermeyen alt dizinleri dışlamanız ve yine de dizin yapısını
korumanız gerekiyorsa

1
-Dahillerin sırasının ne olduğunu nasıl bildin anlamıyorum?
Charlie Parker

1
Yalnızca tek bir dosya türü göndermek istediğim özyinelemeli dizinlerim varsa, bir kişi komutu nasıl oluşturur? Görünüşe göre bunu sadece hedef dizin için yapıyor.
Charlie Parker

15

Bir ek: Dosyaları uzantılarına göre yalnızca tek bir dizinde eşitlemeniz gerekiyorsa (özyineleme olmadan) aşağıdaki gibi bir yapı kullanmalısınız:

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

Dikkatinizi ilk noktadaki noktaya verin --include. --no-rbu yapıda çalışmıyor.

DÜZENLE:

Değerli yorumlarınız için gbyte.co'ya teşekkürler!


1
bayrakların sırasının ne olması ve neleri içermesi gerektiğini nasıl bildiniz?
Charlie Parker

1
@CharlieParker, çünkü rsync includeve excludeseçeneklerini belirtildikleri sırayla kullanır . Buna ek olarak ilk eşleşeninde durur. Dolayısıyla, --exclude '*'bu örnekte ilk sırada belirtirsek , rsync hiçbir şey yapmayacaktır. Daha fazla açıklama için adama bakın.
Serge Roussak

bana her bayrağın ne yaptığını açıklayabilir misin? İlk bayrak -- include './' , kaynak dizin yolundaki her şeyi içermek mi? Sonra bir sonraki '--include' .ext '', belirtilen kaynak yolundaki belirli dosyayı içerir .extve ardından dışlama, başka hiçbir şey göndermeyin diyor --exclude '*'? Bu doğru mu?
Charlie Parker

1
Yalnızca tek bir dosya türü göndermek istediğim özyinelemeli dizinlerim varsa, bir kişi komutu nasıl oluşturur? Görünüşe göre bunu sadece hedef dizin için yapıyor.
Charlie Parker

1
Bunun için teşekkürler! Gerekiyor --include '*.ext've gerekmiyor--include '.ext'
gbyte

13

İşte man sayfasının önemli kısmı:

Aktarılacak dosyaların / dizinlerin listesi oluşturulduğundan, rsync, sırayla dahil etme / dışlama kalıpları listesine göre aktarılacak her adı kontrol eder ve ilk eşleşen modele göre hareket edilir: eğer bu bir dışlama modeliyse, o zaman o dosya atlandı; bir içerme kalıbı ise, o zaman bu dosya adı atlanmaz; eşleşen bir desen bulunmazsa, dosya adı atlanmaz.

Özetlemek:

  • Herhangi bir kalıbın eşleşmemesi, dosyanın kopyalanacağı anlamına gelir!
  • Algoritma, herhangi bir kalıp eşleştiğinde kapanır

Ayrıca, eğik çizgiyle biten bir şey dizinlerle eşleşir ( find -type dyapacağı gibi ).

Bu yanıtı yukarıdan ayıralım.

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"
  1. Hiçbir dizini atlamayın
  2. Hiçbir .shdosyayı atlamayın
  3. Her şeyi atla
  4. (Örtük olarak hiçbir şeyi atlamayın, ancak yukarıdaki kural varsayılan kuralın hiç olmasını engeller.)

Son olarak, --prune-empty-directoriesilk kuralı her yerde boş dizinler yapmaktan korur.


Neler olduğunu açıkladığın için çok teşekkür ederim. Şimdi komutu unutmamam için çok daha iyi bir şans var.
MohamedEzz

3
'' Algoritma herhangi bir örüntü eşleştiğinde kapanır " - bu anahtardır ve daha yüksek puan alan yanıtların hiçbiri bunu burada yaptığınız kadar açık ve açık bir şekilde açıklamaz. Elbette bu bir şekilde man sayfasında ve eğer ben Her şeyi dikkatlice okudum, bunu görmüştüm. Yine de teşekkürler.
TheDudeAbides

0

Birisi bunu ararsa… Sadece belirli dosya ve klasörleri yeniden senkronize etmek istedim ve bunu şu komutla yapmayı başardım: rsync --include-from=rsync-files

Rsync dosyalarıyla:

my-dir/
my-file.txt

- /*

0

Bu kullanışlı işlevi yazdım ve bash komut dosyalarımı veya ~/.bash_aliases. Bash ile Linux'ta yerel olarak test edilmiş ve awkyüklenmiş senkronizasyon . İşe yarıyor

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
}

Avantajlar:

Daha fazla argüman (yani --dry-run) eklemek istendiğinde kısa kullanışlı ve genişletilebilir .

Misal:

selrsync 'tsv,csv' ./source ./target --dry-run
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.