Rsync फ़िल्टर: केवल एक पैटर्न की प्रतिलिपि बनाना


128

मैं एक ऐसी डायरेक्टरी बनाने की कोशिश कर रहा हूं, जिसमें सभी और केवल मेरी पीडीएफ लाटेक से संकलित हों। मुझे प्रत्येक प्रोजेक्ट को एक अलग फ़ोल्डर में रखना पसंद है, सभी एक बड़े फ़ोल्डर में रखे जाते हैं LaTeX। इसलिए मैंने दौड़ने की कोशिश की:

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

जो सभी pdfs को खोजना चाहिए ~/LaTeX/और उन्हें आउटपुट फ़ोल्डर में स्थानांतरित करना चाहिए । यह काम नहीं करता है। यह बताता है कि यह " *.pdf" के लिए कोई मैच नहीं मिला है । यदि मैं इस फ़िल्टर को छोड़ देता हूं, तो कमांड सभी प्रोजेक्ट फ़ोल्डर में सभी फाइलों को LaTeX के अंतर्गत सूचीबद्ध करता है। तो यह * .pdf फ़िल्टर के साथ एक समस्या है। मैंने ~/अपने होम डाइरेक्टरी में पूरे रास्ते से बदलने की कोशिश की , लेकिन इसका असर नहीं हुआ।

मैं, zsh का उपयोग कर रहा हूँ। मैंने बैश में भी यही काम करने की कोशिश की और यहां तक कि फिल्टर के साथ जो हर उपनिर्देशिका में हर एक फाइल को सूचीबद्ध करता है ... यहां क्या हो रहा है?

मेरे PDF को केवल फ़िल्टर समझने में rsync क्यों नहीं है?


ठीक। इसलिए अपडेट करें: नहीं, मैं कोशिश कर रहा हूं

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

और यह मुझे पूरी फाइल सूची देता है। मुझे लगता है क्योंकि सब कुछ पहले पैटर्न से मेल खाता है ...


उह, आप सही प्रतीत हो रहे हैं ... मुझे लगता है कि मेरे जवाब (zsh के **पैटर्न का उपयोग करके ) को काम करना चाहिए, हालांकि।
मार्सेल स्टिमबर्ग

जवाबों:


249

टी एल, डी आर:

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

Rsync गंतव्य के लिए स्रोत (ओं) को कॉपी करता है। यदि आप *.pdfस्रोत के रूप में पास करते हैं, तो शेल .pdfइसे वर्तमान निर्देशिका में एक्सटेंशन के साथ फ़ाइलों की सूची में विस्तारित करता है। कोई पुनरावर्ती ट्रैवर्सल नहीं होता है क्योंकि आपने किसी निर्देशिका को स्रोत के रूप में पारित नहीं किया है।

तो आपको चलाने की आवश्यकता है rsync -a ~/LaTeX/ ~/Output/, लेकिन .pdfकेवल फ़ाइलों को कॉपी करने के लिए rsync को बताने के लिए फ़िल्टर के साथ । जब आप मैनुअल पढ़ते हैं तो रुपीस के फ़िल्टर नियम चुनौतीपूर्ण लग सकते हैं, लेकिन आप कुछ सरल नियमों के साथ कई उदाहरणों का निर्माण कर सकते हैं।

  • निष्कर्ष और बहिष्करण:

    • : नाम या स्थान से फ़ाइलों को छोड़कर आसान है --exclude=*~, --exclude=/some/relative/location(जैसे यह शामिल नहीं स्रोत तर्क के सापेक्ष ~/LaTeX/some/relative/location)।
    • यदि आप केवल कुछ फ़ाइलों या स्थानों से मेल खाना चाहते हैं, तो उन्हें शामिल करें, उनमें से प्रत्येक निर्देशिका को शामिल करें (उदाहरण के लिए --include=*/), फिर बाकी को बाहर करें --exclude='*'। यह है क्योंकि:
    • यदि आप किसी निर्देशिका को बाहर करते हैं, तो यह नीचे दी गई हर चीज़ को बाहर कर देता है। बहिष्कृत फ़ाइलों पर विचार नहीं किया जाएगा।
    • यदि आप एक निर्देशिका शामिल करते हैं, तो यह स्वचालित रूप से इसकी सामग्री को शामिल नहीं करता है। हाल के संस्करणों में, --include='directory/***'ऐसा करेंगे।
    • प्रत्येक फ़ाइल के लिए, पहला मिलान नियम लागू होता है (और जो कुछ भी कभी भी मेल नहीं खाता है)।
  • पैटर्न:

    • यदि किसी पैटर्न में ए नहीं है /, तो यह फ़ाइल नाम सैंस डायरेक्टरी पर लागू होता है।
    • यदि कोई पैटर्न समाप्त होता है /, तो यह केवल निर्देशिकाओं पर लागू होता है।
    • यदि एक पैटर्न के साथ शुरू होता है /, तो यह उस निर्देशिका से पूरे पथ पर लागू होता है जिसे तर्क के रूप में पारित किया गया था rsync
    • *एकल निर्देशिका घटक का कोई विकल्प (यानी कभी मेल नहीं खाता /); **किसी भी पथ प्रतिस्थापन से मेल खाता है।
  • यदि कोई स्रोत तर्क एक के साथ समाप्त होता है /, तो इसकी सामग्री की प्रतिलिपि बनाई जाती है ( प्रत्येक के लिए rsync -r a/ bबनाता b/fooहै a/foo)। अन्यथा निर्देशिका ही कॉपी किया जाता है ( rsync -r a bबनाता है b/a)।


इस प्रकार यहां हमें *.pdfउन निर्देशिकाओं को शामिल करने, उन्हें शामिल करने और बाकी सभी चीजों को शामिल करने की आवश्यकता है।

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

ध्यान दें कि यह सभी निर्देशिकाओं को कॉपी करता है, यहां तक ​​कि जिन में कोई मेल नहीं है फ़ाइल या उपनिर्देशिका जिसमें एक है। यह --prune-empty-dirsविकल्प के साथ टाला जा सकता है (यह एक सार्वभौमिक समाधान नहीं है क्योंकि आप एक निर्देशिका को स्पष्ट रूप से मिलान करके भी कॉपी नहीं कर सकते हैं, लेकिन यह एक दुर्लभ आवश्यकता है)।

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

मेरे समाधान के विपरीत (zsh के **पैटर्न का उपयोग करके ), यह लक्ष्य संरचना में निर्देशिका संरचना को फिर से बनाता है। मुझे यकीन नहीं है कि यह वही है जो ओपी चाहता है ...
मार्सेल स्टिमबर्ग

मैं केवल एक निर्देशिका को शामिल करना चाहता हूं और बाकी सभी निर्देशिकाओं को /etc/lsyncd/lsyncd.conf.luaफ़ाइल में शामिल करना चाहता हूं । कोई विचार है?
धादुक मितेश

@DhadukMitesh मैं lsyncd से परिचित नहीं हूँ। आपको इसे एक नया प्रश्न पूछना चाहिए।
गाइल्स

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

डिफ़ॉल्ट सब कुछ शामिल करने के लिए है, इसलिए आपको उन सभी फ़ाइलों को शामिल करने के बाद स्पष्ट रूप से बाहर करना होगा जिन्हें आप स्थानांतरित करना चाहते हैं। फ़ाइलों को वास्तव में स्थानांतरित करने के लिए -dry-run निकालें।

यदि आप इसके साथ शुरू करते हैं:

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

फिर लालची मिलान सब कुछ सही बाहर कर देगा।

अगर तुम कोशिश करो:

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

तब शीर्ष स्तर के फ़ोल्डर में केवल पीडीएफ फाइलों को स्थानांतरित किया जाएगा। यह किसी भी निर्देशिका का पालन नहीं करेगा, क्योंकि उन लोगों को '*' द्वारा बाहर रखा गया है।


2
2014-03-17 के अनुसार यह सबसे अच्छा उत्तर है, क्योंकि यह मूल पोस्टर प्रश्न को बिल्कुल हल करता है । कृपया इसे वोट करें! यदि आप --prune-empty-dirs(या शॉर्टकट -m) जोड़ते हैं, तो आप अपने आप को गंतव्य पर कई खाली निर्देशिकाओं को भी छोड़ देते हैं, बेशक आप उन्हें अनुस्मारक या संरचनात्मक खाका के रूप में चाहते हैं।
पोर्ग

1
सबसे अच्छा जवाब, --include = "* /" कुंजी है।
मार्टिन कोनिसेक

मैं केवल एक निर्देशिका को शामिल करना चाहता हूं और बाकी सभी निर्देशिकाओं को /etc/lsyncd/lsyncd.conf.luaफ़ाइल में शामिल करना चाहता हूं । कोई विचार है?
धादुक मितेश

15

यदि आप एक पैटर्न का उपयोग करते हैं *.pdf, तो शेल उस पैटर्न को "विस्तारित" करता है, अर्थात यह मौजूदा निर्देशिका में सभी मैचों के साथ पैटर्न को बदलता है। आपके द्वारा चलाए जा रहे कमांड (इस मामले में rsync) इस तथ्य से अनजान है कि आपने एक पैटर्न का उपयोग करने की कोशिश की है।

जब आप zsh का उपयोग कर रहे होते हैं , तो एक आसान उपाय होता है, हालांकि: **पैटर्न का उपयोग फ़ोल्डरों को पुनरावर्ती रूप से मिलान करने के लिए किया जा सकता है। इसे इस्तेमाल करे:

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

कि वर्तमान निर्देशिका के भीतर कहीं से सभी pdfs कॉपी और ~ / LaTeX / से ~ / आउटपुट के लिए सब कुछ नहीं होगा?
सामब

मुझे लगता है कि आप का मतलब था rsync -avn ~/LaTeX/**/*.pdf ~/Output, लेकिन समाधान के साथ --includeऔर अधिक स्केलेबल है।
एडम ब्रीटेक

क्षमा करें, जिस आदेश को मैंने हड़बड़ी में गलत समझा था, उसे ठीक किया ... मैं सहमत हूं कि कमांड (सैमबी के संस्करण में) को शामिल करना बेहतर है, हालांकि यह rsync के लिए थोड़ा अधिक जटिल और विशिष्ट है, जबकि **अन्य स्थितियों में भी उपयोगी हो सकता है।
मार्सेल स्टिमबर्ग

1
बैश 4 ने भी यही फीचर अपनाया है। ओह, और आपको यहाँ rsync की आवश्यकता नहीं है, cp करेगा। कुछ सिस्टम पर, यदि बहुत सारी फाइलें हैं, तो यह cd ~/Latex && cp -p **/*.pdf ~/Output"कमांड लाइन बहुत लंबी" त्रुटि से बचने के लिए करने में मदद करता है ।
जिल्स

1
ध्यान दें कि rsync का उपयोग फ़िल्टर में शामिल और बाहर करना भी एक ** है जो एक ही काम करता है। आप उद्धरण चिह्नों में रखकर अन्य गोले से * बच सकते हैं।
डैन प्रिट्स

13

आप अपनी समस्या को हल करने के लिए findफ़ाइलों और ( files_to_copy) की एक मध्यवर्ती सूची का उपयोग कर सकते हैं । सुनिश्चित करें कि आप अपनी होम डायरेक्टरी में हैं, फिर:

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

बैश के साथ परीक्षण किया गया।


मुझे लगता है कि खोज सबसे मजबूत उपाय है, लेकिन मैं विकल्प खोजने या उपयोग -execकरने का विकल्प चुनूंगा xargs। कुछ इस तरह:find LaTeX/ -type f -iname "*.pdf" -print0 | xargs -0 -i rsync -avn {} Output/
स्टीवन डी

हाँ ... मैं सुझाव दूंगा कि मैं भी ... हालांकि मुझे लगता है कि rsync ऐसा करने में सक्षम होना चाहिए।
गाबे

यह एक कठिन समस्या के साथ-साथ एक साफ समाधान है: संभवतः मैं इसका उपयोग उन फ़ाइलों को बाहर करने के लिए कर सकता हूं जिनकी दस्तावेज़ वर्ग है standaloneया जिनके पास एक .texही नाम वाली फ़ाइल नहीं है , क्योंकि ये कुछ दस्तावेज़ों में शामिल चित्र होंगे ...
सीमस सिप

2
rsync विकल्प --files-fromस्टड से पढ़ना स्वीकार करता है। यह काम करेगा find LaTeX/ -type f -a -iname "*.pdf" | rsync -avn --files-from=- ~/ ~/Output/
जुआन कैलेरो

9

"शामिल / पद्धति नियम को बाहर निकालें" की धारा से आंकना मैनपेज , जिस तरह से यह करने के लिए है

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

इसके और क्रैब के उत्तर के बीच का महत्वपूर्ण अंतर --include="*/"ध्वज है, जो rsync को आगे जाने और किसी भी निर्देशिका को कॉपी करने के लिए कहता है, जिसे वे नाम देते हैं। यह आवश्यक है क्योंकि rsync एक उपनिर्देशिका में पुनरावृत्ति नहीं करेगा जब तक कि उस उपनिर्देशिका की प्रतिलिपि बनाने का निर्देश नहीं दिया गया हो।

यह भी ध्यान दें कि उद्धरण चिह्न मौजूदा निर्देशिका के सापेक्ष फ़ाइलनामों के विस्तार के प्रयास से शेल को रोकते हैं, और निम्न में से एक कर रहे हैं:

  1. अपने फ़िल्टर को सफल करना और गड़बड़ाना (जैसे कि झंडे के बीच में बहुत अधिक संभावना नहीं है, हालांकि आप वास्तव में कभी नहीं जानते हैं कि कब कोई फ़ाइल नाम बनाएगा --include=foo.pdf...)

  2. असफल, और संभावित रूप से कमांड चलाने के बजाय एक त्रुटि पैदा कर रहा है (जैसा कि आपने खोजा है कि डिफ़ॉल्ट रूप से zsh करता है)।


तो यह केवल PDF और निर्देशिका संरचना की प्रतिलिपि करेगा, जबकि kbrd की फ़ाइलों की प्रतिलिपि बनाएगा, लेकिन संरचना को अनदेखा करेगा?
सीमस

1
हम्म। यह वास्तव में अभी भी कोशिश करता है और सब कुछ कॉपी करने के लिए लगता है, मुझे लगता है कि क्योंकि यह फिल्टर के बिना करता है, इसलिए includeअतिरिक्त सामान पहले से ही वहाँ कुछ भी नहीं बदलता है। यदि आप देखें कि मेरा क्या मतलब है ...
सीमस

7
आपको इसकी आवश्यकता --exclude="*"है --include="*.pdf", या यह सब कुछ स्थानांतरित कर देगा।
jmanning2k

@ jmanning2k: आह। जानकार अच्छा लगा!
सैमब

4

इस बारे में कैसा है:

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

नहीं, man rsyncविकल्प के बाद और स्रोत / डेस्टीनेशन से पहले फ़िल्टर डालता है। मैंने यह कोशिश की और यह काम नहीं किया
सीमस

आपका तरीका वर्तमान फ़ोल्डर में .pdf फाइलें ढूंढता है, लेकिन पुनरावृत्ति नहीं, जैसा कि मैं चाहता हूं। ( aविकल्प संग्रह के लिए है और अन्य चीजों के अलावा यह प्रतिलिपि को पुन: सक्रिय बनाता है।
सीमस

1
उफ़, मेरी बुर। मैंने अपना उत्तर अपडेट कर दिया।
kbyrd

+1 इतने पास होने के लिए, और मुझे इस बारे में एक सुराग देने के लिए कि मैनुअल पेज में संबंधित सामग्री कैसे ढूंढनी है। (उम्मीद है कि मैंने इसे सही भी कर लिया है। :-)
सैमबी

3

यहां कुछ ऐसा है जिसे खोजने के बिना काम करना चाहिए। पहले से पोस्ट किए गए उत्तरों से अंतर फ़िल्टर नियमों का क्रम है। Rsync आदेश में फ़िल्टर नियम बहुत कुछ iptable नियमों की तरह काम करते हैं, पहला नियम जो एक फ़ाइल से मेल खाता है वह है जिसका उपयोग किया जाता है। से मैन्युअल पृष्ठ :

जैसा कि स्थानांतरण करने के लिए फ़ाइलों / निर्देशिकाओं की सूची बनाई गई है, rsync प्रत्येक नाम को बदले में शामिल / बहिष्कृत पैटर्न की सूची के विरुद्ध स्थानांतरित करने के लिए जाँच करता है, और पहले मिलान पैटर्न पर कार्य किया जाता है: यदि यह एक बाहर का पैटर्न है, तो वह फ़ाइल है को छोड़ दिया; यदि यह एक सम्मिलित पैटर्न है तो फ़ाइल नाम को छोड़ दिया नहीं जाता है; यदि कोई मिलान पैटर्न नहीं मिलता है, तो फ़ाइल नाम छोड़ दिया नहीं जाता है।

इस प्रकार, आपको एक कमांड की आवश्यकता है:

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

"**। Pdf" पैटर्न पर ध्यान दें। मैन पेज के अनुसार :

यदि पैटर्न में एक / (एक अनुगामी / गिनती नहीं) या "**" शामिल है, तो यह किसी भी अग्रणी निर्देशिकाओं सहित पूर्ण पथनाम से मेल खाता है। यदि पैटर्न में / या "**" शामिल नहीं है, तो इसे केवल फ़ाइल नाम के अंतिम घटक के साथ मिलान किया जाता है। (याद रखें कि एल्गोरिथ्म को पुनरावर्ती रूप से लागू किया गया है, इसलिए "पूर्ण फ़ाइल नाम" वास्तव में नीचे से शुरू होने वाले फ़ॉर्म से किसी भी पथ का हिस्सा हो सकता है

मेरे छोटे परीक्षण में, यह डायरेक्टरी ट्री को पुनरावृत्ति करने का काम करता है और केवल pdfs का चयन करता है।


आपने वास्तव में कैसे परीक्षण किया? प्रलेखन की मेरी समझ और मेरे प्रायोगिक सत्यापन के अनुसार, आपकी कमान केवल *.pdfटॉपवेल निर्देशिका (लेकिन नहीं ~/LaTeX/foo/bar.pdf) में कॉपी होनी चाहिए ।
गिलीस

@ गिल्स क्रूड। तुम सही हो। मैंने शपथ ली कि मैंने यह परीक्षण किया है और यह काम किया है, लेकिन मैं इसे फिर से बनाना नहीं कर सकता। और अब जब मैं वास्तव में उस आदमी पृष्ठ को पढ़ता हूं जिसे मैंने उद्धृत किया है, तो यह समझ में आता है कि यह काम नहीं करता है। बड़बड़ाना।
स्टीवन डी

1
खैर, मुझे लगा कि मेरा परीक्षण गलत था। मेरा "छोटा परीक्षण" एक निर्देशिका पर था। मेरे पास .net और .pdf फाइलें हैं। मैंने तब एक "परीक्षण" उपनिर्देशिका और एक परीक्षण बनाया। पीडीपी और टेस्टडॉटेक्स। हालाँकि, मैं यह ध्यान देने में विफल रहा कि मेरे शीर्ष स्तर के डायर में एक परीक्षण था। निश्चित रूप से लाटेक्स प्रयोग के कुछ त्वरित होने के कारण।
स्टीवन डी

मुझे अभी भी समझ नहीं आया **। इसका उदाहरण रखना अच्छा होगा। ;)
buhtz

2

यह मेरा पसंदीदा समाधान है:

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

findआदेश से समझ में शामिल / के नियमों को बाहर करने में आसान है rsync:-)

यदि आप केवल पीडीएफ फाइलों को कॉपी करना चाहते हैं, तो बस बदल .jpgदें.pdf

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.