it-swarm-tr.com

Rsync filtresi: yalnızca bir deseni kopyalama

Hepsini ve sadece LaTeX derlenmiş PDF'lerimi barındıracak bir dizin oluşturmaya çalışıyorum. Her projeyi ayrı bir klasörde tutmayı seviyorum, hepsi LaTeX adlı büyük bir klasörde. Bu yüzden koşmayı denedim:

rsync -avn *.pdf ~/LaTeX/ ~/Output/

~/LaTeX/ içindeki tüm pdfs'leri bulmalı ve çıktı klasörüne aktarmalıdır. Bu işe yaramıyor. Bana "*.pdf" İçin eşleşme bulunmadığını söylüyor. Bu filtreden çıkarsam, komut LaTeX altındaki tüm proje klasörlerindeki tüm dosyaları listeler. Bu, * .pdf filtresiyle ilgili bir sorundur. ~/ Yerine ana dizininin tam yolunu koymayı denedim, ancak bunun bir etkisi olmadı.

Zsh kullanıyorum. Ben aynı şeyi bash yapmayı denedim ve hatta with her alt dizindeki her bir dosyayı listeleyen filtre ... Burada neler oluyor?

Neden rsync sadece pdf filtremi anlamıyor?


TAMAM. Yani güncelleme: Hayır deniyorum

rsync -avn --include="*/" --include="*.pdf" LaTeX/ Output/

Ve bu bana tüm dosya listesini veriyor. Sanırım her şey ilk kalıba uyuyor ...

142
Seamus

TL, DR:

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

Rsync kaynak (lar) ı hedefe kopyalar. Kaynak olarak *.pdf İletirseniz, Shell bunu geçerli dizinde .pdf Uzantılı dosyalar listesine genişletir. Hiçbir dizini kaynak olarak geçirmediğiniz için özyinelemeli geçiş olmaz.

Bu nedenle, rsync -a ~/LaTeX/ ~/Output/ Dosyasını çalıştırmanız gerekir, ancak rsync'e yalnızca .pdf Dosyalarını kopyalamasını bildirmek için bir filtre kullanın. Kılavuzu okurken Rsync'in filtre kuralları göz korkutucu görünebilir, ancak birkaç basit kuralla birçok örnek oluşturabilirsiniz.

  • Kapsamalar ve istisnalar:

    • Dosyaları ada veya konuma göre hariç tutmak kolaydır: --exclude=*~, --exclude=/some/relative/location (Kaynak bağımsız değişkenine göre, örneğin ~/LaTeX/some/relative/location Hariçtir).
    • Yalnızca birkaç dosyayı veya konumu eşleştirmek istiyorsanız, bunları ekleyin, bunlara yol açan her dizini ekleyin (örneğin --include=*/ İle), sonra kalanları --exclude='*'. Bunun nedeni ise:
    • Bir dizini hariç tutarsanız, altındaki her şey hariç tutulur. Dışarıda bırakılan dosyalar hiç dikkate alınmayacaktır.
    • Bir dizin eklerseniz, bu otomatik olarak içeriğini içermez. Son sürümlerde --include='directory/***' Bunu yapacak.
    • Her dosya için ilk eşleme kuralı uygulanır (ve hiç eşleşmeyen her şey eklenir).
  • Desenler:

    • Bir desen / İçermiyorsa, sans dosya adı dizini için geçerlidir.
    • Bir desen / İle bitiyorsa, yalnızca dizinler için geçerlidir.
    • Bir desen / İle başlıyorsa, rsync değişkenine bağımsız değişken olarak iletilen dizindeki tüm yol için geçerlidir.
    • * Tek bir dizin bileşeninin herhangi bir alt dizesi (yani hiçbir zaman / İle eşleşmez); ** Herhangi bir yol alt dizesiyle eşleşir.
  • Bir kaynak bağımsız değişkeni bir / İle biterse içeriği kopyalanır (rsync -r a/ b Her b/foo İçin a/foo Oluşturur). Aksi takdirde dizinin kendisi kopyalanır (rsync -r a bb/a Oluşturur).


Bu nedenle burada *.pdf İfadesini eklemeli, bunları içeren dizinleri eklemeli ve diğer her şeyi hariç tutmalıyız.

rsync -a --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

Bunun, eşleşen bir dosya veya bir tane içeren alt dizin içermeyen tüm dizinleri kopyaladığını unutmayın. Bu, --Prune-empty-dirs Seçeneğiyle önlenebilir (evrensel bir çözüm değildir, çünkü bir dizini açıkça eşleştirerek bile kopyalayamazsınız, ancak bu nadir bir gereksinimdir).

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/
rsync -av --include="*/" --include="*.pdf" --exclude="*" ~/Latex/ ~/Output/ --dry-run

Varsayılan, her şeyi dahil etmektir, bu nedenle aktarmak istediğiniz dosyalar dahil olmak üzere her şeyi after hariç tutmanız gerekir. Dosyaları gerçekten aktarmak için --dry-run dosyasını kaldırın.

Şununla başlarsanız:

--exclude '*' --include '*.pdf'

Sonra açgözlü eşleştirme hemen her şeyi dışlar.

Eğer denersen:

--include '*.pdf' --exclude '*' 

Daha sonra yalnızca üst düzey klasördeki pdf dosyaları aktarılır. '*' Tarafından hariç tutulduğu için herhangi bir dizini takip etmez.

30
jmanning2k

*.pdf Gibi bir kalıp kullanırsanız, Kabuk bu kalıbı “genişletir”, yani kalıbı geçerli dizindeki tüm eşleşmelerle değiştirir. Çalıştırdığınız komut (bu durumda rsync) bir desen kullanmaya çalıştığınızın farkında değildir.

zsh kullanırken, kolay bir çözüm var: ** Deseni klasörleri özyinelemeli olarak eşleştirmek için kullanılabilir. Bunu dene:

rsync -avn ~/LaTeX/**/*.pdf ~/Output/
15
Marcel Stimberg

find ve ara dosya listesini (files_to_copy) sorununuzu çözmek için. Ana dizininizde olduğunuzdan emin olun, ardından:

find LaTeX/ -type f -a -iname "*.pdf" > files_to_copy && rsync -avn --files-from=files_to_copy ~/ ~/Output/ && rm files_to_copy

Bash ile test edildi.

13
Derek Frye

manpage öğesinin "INCLUDE/EXCLUDE DESEN KURALLARI" bölümüne bakıldığında, bunu yapmanın yolu

rsync -avn --include="*/" --include="*.pdf" ~/Latex/ ~/Output/

Bu ve kbrd'nin cevabı arasındaki kritik fark --include="*/" flag, rsync'e, adı ne olursa olsun bulmasını ve bulduğu dizinleri kopyalamasını söyler. Bu gereklidir, çünkü rsync o alt dizini kopyalamanız istenmedikçe bir alt dizine geri çekilmez.

Ayrıca, tırnak işaretlerinin Kabuğun kalıpları geçerli dizine göre dosya adlarına genişletmeye çalıştığını ve aşağıdakilerden birini yapmasını engellediğini unutmayın:

  1. Filtrenizi başarılı hale getirmek ve karıştırmak (böyle bir bayrağın ortasında pek olası değildir, ancak birisinin --include=foo.pdf ...)

  2. Başarısız oluyor ve komutu çalıştırmak yerine hata üretiyor olabilir (zsh'ın varsayılan olarak yaptığı gibi).

9
SamB

Bu benim tercih ettiğim çözüm:

find source_dir -iname '*.jpg' -print0 |  rsync -0 -v --files-from=- . destination_dir/

find komutunun anlaşılması, rsync :-) içerme/hariç tutma kurallarından daha kolaydır.

Yalnızca pdf dosyalarını kopyalamak istiyorsanız .jpg ila .pdf

3
guettli

Buna ne dersin:

rsync -avn --include="*.pdf" ~/Latex/ ~/Output/
3
kbyrd

İşte find kullanmadan çalışması gereken bir şey. Önceden gönderilmiş cevaplardan farkı, filtre kurallarının sırasıdır. Bir rsync komutundaki filtre kuralları iptable kurallarına çok benzer, bir dosyanın eşleştiği ilk kural kullanılan kuraldır. manuel sayfa :

Aktarılacak dosyalar/dizinler listesi oluşturuldukça, rsync aktarılacak her adı sırasıyla dahil etme/hariç tutma kalıpları listesine göre denetler ve ilk eşleşen kalıp harekete geçirilir: bir hariç tutma kalıbıysa, o dosya atlanır; bir içerme modeli ise, dosya adı atlanmaz; eşleşen bir desen bulunamazsa, dosya adı atlanmaz.

Bu nedenle, aşağıdaki gibi bir komuta ihtiyacınız vardır:

rsync -avn --include="**.pdf" --exclude="*" ~/LaTeX/ ~/Output/

"**. Pdf" desenine dikkat edin. man sayfası :

kalıp bir/(sondaki/sayılmıyorsa) veya "**" içeriyorsa, önde gelen dizinler de dahil olmak üzere tam yol adıyla eşleştirilir. Desen bir/veya "**" içermiyorsa, yalnızca dosya adının son bileşeniyle eşleştirilir. (Algoritmanın özyinelemeli olarak uygulandığını unutmayın, böylece "tam dosya adı" aslında başlangıç ​​dizininden aşağıya doğru bir yolun herhangi bir bölümü olabilir

Benim küçük test, bu dizin ağacında özyineli olarak çalışır ve yalnızca pdfs seçer.

2
Steven D

Kaynak dizinin içinden yalnızca üstbilgiler (../include) içeren bir dizin oluşturmak için:

rsync -avh --Prune-empty-dirs --exclude="build" --include="*/" --include="*.h" --exclude="*" ./* ../include/

Bu, tüm boş dizinleri ve build dizinini hariç tutar

0
SCG82