एक फ़ाइल में सैकड़ों स्ट्रिंग्स के लिए एक निर्देशिका में हजारों फ़ाइलों को कैसे प्राप्त करें


11

मैं एक grepबयान लिखने की कोशिश कर रहा हूं और यह मुझे मार रहा है। मैं भी arguments list too longत्रुटि मिलने से थक गया हूँ । मेरे पास एक फाइल है, चलो बुलाते हैं subset.txt। इसमें विशिष्ट रेखाओं वाली सैकड़ों लाइनें शामिल हैं जैसे कि MO43312948। मेरी ऑब्जेक्ट डायरेक्टरी में मेरे पास हजारों फाइलें हैं और मुझे उन सभी फाइलों को कॉपी करने की जरूरत है, जिनमें subset.txtएक और डायरेक्टरी में सूचीबद्ध स्ट्रिंग्स हैं ।

मैं ऑब्जेक्ट डायरेक्टरी से मिलान वाली फ़ाइलों को वापस करने के लिए इसके साथ शुरू करने की कोशिश कर रहा था।

grep -F "$(subset.txt)" /objects/*

मैं `बैश: / बिन / grep: तर्क सूची बहुत लंबी` `प्राप्त करता रहता हूं


6
आपने "$(subset.txt)"कमान क्यों उस तरह से रखी है? यह कमांड प्रतिस्थापन है , जो आपके शेल को निष्पादित करेगा subset.txt (जैसे कि यह एक कमांड या स्क्रिप्ट था)।
JigglyNaga

जवाबों:


23

आप करने के लिए एक लक्ष्य के रूप में एक निर्देशिका पारित कर सकते हैं grepके साथ -Rऔर साथ निवेश पैटर्न की एक फ़ाइल -f:

  -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.  If this option is used
          multiple  times  or  is  combined with the -e (--regexp) option,
          search for all patterns given.  The  empty  file  contains  zero
          patterns, and therefore matches nothing.

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

तो, आप देख रहे हैं:

grep -Ff subset.txt -r objects/

आप के साथ मिलान फ़ाइलों की सूची प्राप्त कर सकते हैं:

grep -Flf subset.txt -r objects/

इसलिए, यदि आपकी अंतिम सूची बहुत लंबी नहीं है, तो आप बस कर सकते हैं:

 mv $(grep -Flf subset.txt -r objects/) new_dir/

यदि वह argument list too longत्रुटि देता है , तो उपयोग करें:

grep -Flf subset.txt -r objects/ | xargs -I{} mv {} bar/

और अगर आपके फ़ाइल नामों में स्थान या अन्य अजीब अक्षर हो सकते हैं, तो उपयोग करें (GNU मानकर grep):

grep -FZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

अंत में, यदि आप बाइनरी फ़ाइलों को बाहर करना चाहते हैं, तो उपयोग करें:

grep -IFZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

… या mvप्रत्येक तर्क के साथ संभावित हजारों आह्वान से बचने के लिए : ... | xargs -0 mv -t bar/(अपने विकल्प mvका समर्थन करते हुए -t)।
डेविड फ़ॉस्टर

11

उपयोग

grep -F -f subset.txt 

subset.txtफ़ाइल से पढ़ने के लिए grep बताने के लिए ।

आप फ़ाइल को खोजने के लिए खोज का उपयोग कर सकते हैं।

find . -type f -exec grep -F -f subset.txt {} \;

या

find . -type f -exec grep -F -f subset.txt {}  +

अन्य के findबजाय उपयोग करने का कोई लाभ -rजो आप अतिरिक्त फ़िल्टरिंग करते हैं?
phk

1
@phk grep -rनियमित फ़ाइलों के लिए सहानुभूति में खोज करता है, जो वांछनीय हो सकता है या नहीं भी हो सकता है (यदि वे एक ही पेड़ के अंदर इंगित करते हैं, तो आप एक ही फ़ाइल को दो बार खोज रहे हैं; यदि वे बाहर इंगित करते हैं, तो आप एक ऐसी फ़ाइल खोज रहे हैं जो हो सकता है या नहीं। वांछित हो)।
गिलेस एसओ- बुराई को रोकना '

आधुनिक संस्करणों में grepप्रतीकात्मक लिंक के साथ अपनी बातचीत को नियंत्रित करने के लिए विकल्प हैं ( man grepवर्तमान प्रणाली के लिए बारीकियों को निर्धारित करने के लिए)। एक पुनरावर्ती प्रत्येक फ़ाइल पर व्यक्तिगत रूप से चलने की तुलना में बहुत तेज़ grepहोगा । grepfind
पेरी

1
@ क्या आप इस बारे में निश्चित हैं? क्यों? यह भी ध्यान दें कि यह उत्तर उपयोग कर रहा है -exec +, इसलिए यह फ़ाइलों को समूहित करेगा और प्रति फ़ाइल एक grep नहीं चलाएगा।
terdon

मैं सही खड़ा हूं, मैं -exec {} +बनाम के अलग-अलग शब्दार्थों से अनजान था -exec {} \;... आप हर दिन कुछ नया सीखते हैं (मैं अभी भी कोई कारण नहीं देखता कि एक एकल पुनरावर्ती grepअभ्यस्त प्रक्रिया निर्माण और पैटर्न पार्सिंग ओवरहेड के कारण एकाधिक grepएस रन से अधिक तेज क्यों नहीं है - findमैं हूं कि वापस करने के लिए हाथ करने के लिए विशिष्ट संख्या नहीं है)।
पेरी

3

यदि आप grep को और भी अधिक गति देना चाहते हैं, तो आप इसे चलाने से पहले अपने शेल में लोकेल सेट कर सकते हैं, अर्थात "LC_ALL = c" का उपयोग करें। यह grep में इनहेरिट किया जाएगा और आवश्यक नहीं होने पर यूनिकोड प्रोसेसिंग को अक्षम कर देगा और कुछ मामलों में नाटकीय रूप से grep को गति दे सकता है। इसका दस्तावेजीकरण करने वाला एक महान ब्लॉग http://www.inmotionhosting.com/support/website/ssh/speed-up-grep-searches-with-lc-all पर पाया जा सकता है । यह ट्रिक bash शेल स्क्रिप्ट्स को भी गति दे सकती है, न कि सिर्फ grep को।

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