rsync केवल कुछ फ़ाइलों को शामिल करने के लिए regex का उपयोग कर रहा है


11

मैं असंवेदनशील तरीके से अपने फ़ाइल नाम पैटर्न, केस असंवेदनशील के आधार पर कुछ फ़ाइलों को कॉपी करने के लिए rsync चलाने की कोशिश कर रहा हूं । यह वही है जो मैंने rsync चलाने के लिए किया है:

$ rsync -avvz --include ='*/' --include='.*[Nn][Aa][Mm][E].*' --exclude='*' ./a/ ./b/

कुछ भी कॉपी नहीं किया जाता है, डिबग आउटपुट दिखाता है:

[sender] hiding file 1Name.txt because of pattern *
[sender] hiding file 1.txt because of pattern *
[sender] hiding file 2.txt because of pattern *
[sender] hiding file Name1.txt because of pattern *
[sender] hiding directory test1 because of pattern *
[sender] hiding file NaMe.txt because of pattern *

मैंने उपयोग करने की कोशिश की है: --include='*[Nn][Aa][Mm][E]*'और अन्य संयोजन लेकिन यह अभी भी नहीं जाता है।

कुछ फ़ाइलों को शामिल करने के लिए regex का उपयोग करने के बारे में कोई विचार?


4
आप का उपयोग क्यों कर रहे हैं --exclude='*'?

2
इसलिए इसमें वह सब कुछ शामिल नहीं है जो शामिल नहीं है।

'फाइल को छुपाना 1Name.txt पैटर्न के कारण ' यह इंगित करता है: - "क्या यह --exclude नियम कमांड में होना चाहिए?" या यदि आप कुछ फ़ाइलों को बाहर करना चाहते हैं तो एक " " क्यों
अक्षय पाटिल

जवाबों:


5

rsync regex नहीं बोलता है। आप खोज और grep को सूचीबद्ध कर सकते हैं, हालांकि यह थोड़ा रहस्यमय हो जाता है। लक्ष्य फ़ाइलों को खोजने के लिए:

find a/ |
grep -i 'name'

लेकिन वे सभी "/ a" के साथ उपसर्ग कर रहे हैं - जो समझ में आता है, लेकिन जो हम समाप्त करना चाहते हैं वह rsync के लिए स्वीकार्य पैटर्न को शामिल करने की एक सूची है, और "r /" के लिए "a /" उपसर्ग काम नहीं करता है ' इसे कट के साथ हटा देंगे:

find . |
grep -i 'name' |
cut -d / -f 2-

अभी भी एक समस्या है - हम अभी भी उपनिर्देशिकाओं में फ़ाइलों को याद करेंगे, क्योंकि rsync बाहर की सूची में निर्देशिका नहीं खोजता है। मैं किसी भी मेल खाने वाली फ़ाइल की उपनिर्देशिकाओं को शामिल करने के लिए awk का उपयोग करने जा रहा हूँ, जिसमें शामिल हैं पैटर्न:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'

सभी को छोड़ दिया जाता है कि सूची को rsync पर भेजना है - हम मानक इनपुट पर rsync को पैटर्न की सूची प्रदान करने के लिए तर्क --include-from = का उपयोग कर सकते हैं। तो, कुल मिलाकर:

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

ध्यान दें कि स्रोत निर्देशिका 'a' को दो अलग-अलग रास्तों - "a /" और "./a/" के माध्यम से संदर्भित किया जाता है। यह सूक्ष्म लेकिन महत्वपूर्ण है। चीजों को अधिक सुसंगत बनाने के लिए मैं एक अंतिम परिवर्तन करने जा रहा हूं, और हमेशा स्रोत निर्देशिका को "./a/" के रूप में संदर्भित करता हूं। हालांकि, इसका मतलब है कि कट कमांड को बदलना होगा क्योंकि परिणाम से सामने वाले स्थान पर "./" होगा:

find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

इसे चलाने की कोशिश की, कट कमांड के साथ मुद्दों में भाग गया। ऐसा लगता -tहै कि एक वैध स्विच है।

edit: i

क्षमा करें, -d होना चाहिए। मैंने sed का उपयोग करना शुरू कर दिया और फिर कटौती करने के लिए बदल दिया क्योंकि मुझे लगा कि यह स्पष्ट था, लेकिन मेरे आदेशों को संपादित करना भूल गया: S

अनुसरण करें: तर्क लेने के लिए ट्रिक को संपादित करने की कोशिश की गई ($ 1 = path_to_search, $ 2 उदाहरण के लिए पैटर्न के रूप में) जैसा कि मैं एक्सटेंशन के फ़ाइल नाम + मिश्रण का मिलान कर रहा हूं। वह भाग ठीक काम करता है, मुझे अपेक्षित सूची मिली है, हालाँकि rsync कॉपी करने में विफल है। यह उदाहरण के रूप में एकल नाम चरित्र निर्देशिका के साथ काम करने के लिए लगता है (क) मेरा अनुमान है कि कट कमांड को माता-पिता या स्रोत डीआईआर के आधार पर पात्रों को काटने के लिए संशोधित करना होगा? किंडा किस तरह से हार गया:
user1957413

आह, तुम काफी सही हो। यह किसी भी लम्बाई के निर्देशिका नाम पर काम करना चाहिए, लेकिन जैसे ही आप वर्तमान निर्देशिका के बाहर एक निर्देशिका का उल्लेख करेंगे (क्योंकि उपसर्ग भाग में स्लैश की एक अलग संख्या होगी)। इसे ठीक करने के लिए, संभवतः कट के बजाय sed "s#^$1/*##" सेड का उपयोग करना सबसे आसान है, जैसे: बुयुट जो उन रास्तों पर टूट जाएगा जिनमें एक # होता है। यह तय करने के लिए कि हमें आने वाली डायरेक्टरी नाम को उद्धृत करना है: prefix=$(echo "$1" | sed 's#/#\\/#g')और फिर sed "s/^$prefix\\/*//" बैश कोटिंग की आत्महत्याएं एक बुरा सपना है;)
sqweek

7

मैं rsync के फ़िल्टर विकल्प का उपयोग करने का सुझाव दूंगा। अपने उदाहरण के लिए बस टाइप करें:

rsync -vam -f'+ *[Nn][Aa][Mm][E]*' -f'+ */' -f'- *' a b

पहला फ़िल्टर नियम rsync को बताता है कि क्या पैटर्न शामिल हैं। दूसरे नियम की जरूरत है कि rsync को उसके ट्रैवर्सल पर सभी निर्देशिकाओं का निरीक्षण करने के लिए कहा जाए। खाली डायरियों को शामिल करने से रोकने के लिए उन्हें -mविकल्प द्वारा स्पष्ट रूप से बाहर रखा गया है। अंतिम फ़िल्टर नियम सभी शेष पैटर्नों को निपटाने के लिए rsync को बताता है जो अभी तक मेल नहीं खाते थे।


मिठाई। यह काम भी किया। मुझे फ़ोल्डर बी के अंदर मिल रहा था, जो स्रोत और गंतव्य के रूप में ए / बी का उपयोग करके तय हो गया। धन्यवाद!
user1957413

उपयोग -f '+ * [एनएन] [एए] [एमएम] [ई] **' (अंत में दो सितारे) एक विशिष्ट नाम के साथ सभी निर्देशिकाओं की सामग्री को शामिल करने के लिए।
फोबिक

2

यदि आप ZSH का उपयोग करते हैं तो आप केस संवेदनशीलता को बंद करने के लिए (#i) ध्वज का उपयोग कर सकते हैं। उदाहरण:

$ touch NAME
$ ls (#i)*name*
NAME

ZSH बहिष्करणों का भी समर्थन करते हैं, जो नियमित मार्ग की तरह निर्दिष्ट हैं, लेकिन उनके पास एक प्रारंभिक ~ है

$ touch aa ab ac
$ ls *~*c
aa ab

आप श्रृंखला बहिष्करण कर सकते हैं:

$ ls *~*c~*b
aa

अंत में आप निर्दिष्ट कर सकते हैं कि आप किस तरह की फाइल चाहते हैं (डायरेक्टरी, फाइल आदि)। यह फ़ाइल के लिए निर्देशिका (और) के लिए (/) के साथ किया जाता है।

$ touch file
$ mkdir dir
$ ls *(.)
file

इस सब के आधार पर, मैं उस आदेश को निम्नानुसार करूंगा:

rsync -avvz *(/) (#i)*name* ./a/ ./b/

(मुझे इन चयनकर्ताओं के साथ बहिष्करण की आवश्यकता नहीं है)


1

@ sqweek का उत्तर बहुत बढ़िया है, हालांकि मुझे संदेह है कि उसके पास awkमूल निर्देशिका बनाने के लिए उसकी स्क्रिप्ट में एक बग है , क्योंकि यह मुझे देता है जैसे:

$ echo a/b/c/d | awk -F/ '{print; while(/\//) {sub("/[^/]*", ""); print}}'
a/b/c/d
a/c/d
a/d
a

मैं gensubइसके बजाय का उपयोग करके इसे ठीक करने में सक्षम था :

$ echo a/b/c/d | awk -F/ '{print; while(/\//) { $0=gensub("(.*)/[^/]*", "\\1", "g"); print}}'
a/b/c/d
a/b/c
a/b
a

तो, उसका पूरा समाधान, awkथोड़ा बदला हुआ, होगा:

find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) { $0=gensub("(.*)/[^/]*", "\\1", "g"); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

धन्यवाद। मेरे जवाब को पंक्ति के अंत में रेगेक्स को एंकरिंग के बराबर फिक्स के साथ संपादित किया ( sub("/[^/]*$"))।
वर्गवीक

0

C # स्क्रिप्ट के साथ कोशिश की गई है क्योंकि भाषा मेरे पास सबसे अधिक अनुभव है। मैं उन फ़ाइलों की सूची बनाने में सक्षम हूं, जिन्हें मैं शामिल करना चाहता हूं, लेकिन कोई rsync अभी भी बता रहा है कि मुझे किराया लेना है। यह फ़ोल्डर्स बनाता है, लेकिन यह फ़ाइलों को अनदेखा करता है। यहाँ वही है जो मुझे मिला है ।।

पहले निर्देशिका की सामग्री:

~/mono$ ls -l
total 24
drwxr-xr-x 5 me me 4096 Jan 15 00:36 a
drwxr-xr-x 2 me me 4096 Jan 15 00:36 b
drwxr-xr-x 3 me me 4096 Jan 14 00:31 bin
-rw-r--r-- 1 me me 3566 Jan 15 00:31 test.cs
-rwxr-xr-x 1 me me 4096 Jan 15 00:31 test.exe
-rwxr--r-- 1 me me  114 Jan 14 22:40 test.sh

फिर C # स्क्रिप्ट का आउटपुट:

~/mono$ mono test.exe

/a/myfile/myfileseries.pdf
/a/myfile2/testfile.pdf

और डिबग आउटपुट:

~/mono$ mono test.exe | rsync -avvvz --include='*/' --include-from=- --exclude='*' ./a/ ./b/
[client] add_rule(+ */)
[client] parse_filter_file(-,20,3)
[client] add_rule(+ /a/myfile/myfileseries.pdf)
[client] add_rule(+ /a/myfile2/testfile.pdf)
[client] add_rule(- *)
sending incremental file list
[sender] make_file(.,*,0)
[sender] hiding file 1Name.txt because of pattern *
[sender] showing directory myfile2 because of pattern */
[sender] make_file(myfile2,*,2)
[sender] hiding file 1.txt because of pattern *
[sender] hiding file 2.txt because of pattern *
[sender] hiding file Name1.txt because of pattern *
[sender] showing directory test1 because of pattern */
[sender] make_file(test1,*,2)
[sender] hiding file NaMe.txt because of pattern *
[sender] showing directory myfile because of pattern */
[sender] make_file(myfile,*,2)
send_file_list done
send_files starting
[sender] hiding file myfile/myfileseries.pdf because of pattern *
[sender] hiding file myfile2/testfile.pdf because of pattern *
[sender] hiding file test1/test.txt because of pattern *

0

[संपादित करें] यह केवल स्थानीय स्तर पर काम करता है। दूरस्थ रास्तों के लिए, निर्देशिका संरचना पहले बनाई जानी है।

स्वीकृत उत्तर की तुलना में अधिक सरल; उपयोग करें - फाइल-से, जिसमें स्वचालित रूप से मूल निर्देशिकाएं शामिल हैं और% P के साथ फ़ाइल पथ प्रिंट करें

find /tmp/source -wholename '*[Nn][Aa][Mm][E]*' -printf '%P\n' | rsync -vzrm --exclude='*/' --files-from=- /tmp/source/ /tmp/target/

आप केवल उपयोग करने के लिए तो findऔर rsync

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