टर्मिनल में बहु-थ्रेडेड grep कैसे शुरू करें?


38

मेरे पास एक फ़ोल्डर है जिसमें 2 जीबी की 250+ फाइलें हैं। मुझे उन फ़ाइलों में एक स्ट्रिंग / पैटर्न की खोज करने की आवश्यकता है और एक outputफ़ाइल में परिणाम का उत्पादन करता है । मुझे पता है कि मैं निम्नलिखित कमांड चला सकता हूं, लेकिन यह बहुत धीमी है !!

grep mypattern * > output

मैं इसे गति देना चाहता हूं। जावा में एक प्रोग्रामर होने के नाते, मुझे पता है कि प्रक्रिया को तेज करने के लिए मल्टी-थ्रेडिंग का उपयोग किया जा सकता है। मैं grep"मल्टी-थ्रेडेड मोड" में शुरू करने और आउटपुट को एक एकल outputफ़ाइल में लिखने के तरीके पर अटक गया हूं ।




1
निश्चित रूप से फ़ाइलों का एक बड़ा संग्रह खोजना एक समस्या का क्लासिक उदाहरण है जो IO बाध्य है। इसलिए कई थ्रेड का उपयोग करने से मदद नहीं मिलेगी।
जोनाथन हार्टले

जवाबों:


31

इसके लिए दो आसान उपाय हैं। मूल रूप से, का उपयोग कर xargsया parallel

xargs दृष्टिकोण:

आप उपयोग कर सकते हैं xargsके साथ findइस प्रकार है:

find . -type f -print0  | xargs -0 -P number_of_processes grep mypattern > output

जहाँ आप number_of_processesउन अधिकतम प्रक्रियाओं को प्रतिस्थापित करेंगे जिन्हें आप लॉन्च करना चाहते हैं। हालाँकि, यह सुनिश्चित करने की गारंटी नहीं है कि आपका प्रदर्शन I / O सीमित है। जिस स्थिति में आप I / Os के इंतज़ार में खोए समय की भरपाई के लिए अधिक प्रक्रियाएँ शुरू करने का प्रयास कर सकते हैं।

इसके अलावा, खोज को शामिल करने के साथ, आप केवल फ़ाइल पैटर्न के बजाय अधिक उन्नत विकल्प निर्दिष्ट कर सकते हैं, जैसे संशोधन समय, आदि ...

इस दृष्टिकोण के साथ एक संभव मुद्दा जैसा कि स्टीफन की टिप्पणियों द्वारा समझाया गया है, अगर कुछ फाइलें हैं, तो xargsउनके लिए पर्याप्त रूप से कई प्रक्रियाएं शुरू नहीं हो सकती हैं। एक समाधान यह निर्दिष्ट -nकरने के लिए विकल्प का उपयोग xargsकरना होगा कि एक समय में पाइप से कितने तर्क लेने चाहिए। सेटिंग प्रत्येक एकल फ़ाइल के लिए एक नई प्रक्रिया शुरू करने के लिए -n1मजबूर करेगी xargs। यह एक वांछित व्यवहार हो सकता है यदि फाइलें बहुत बड़ी हैं (जैसे कि इस प्रश्न के मामले में) और अपेक्षाकृत कम संख्या में फाइलें हैं। हालाँकि, यदि फ़ाइलें स्वयं छोटी हैं, तो एक नई प्रक्रिया शुरू करने का ओवरहेड समानता के लाभ को कम कर सकता है, इस मामले में एक बड़ा -nमूल्य बेहतर होगा। इस प्रकार, -nफ़ाइल आकार और संख्या के अनुसार विकल्प ठीक हो सकता है।

समानांतर दृष्टिकोण:

इसका एक और तरीका है ओले तांगे जीएनयू समानांतर उपकरण का उपयोग करना parallel, ( यहां उपलब्ध है )। यह समानता पर अधिक अच्छा अनाज नियंत्रण प्रदान करता है और यहां तक ​​कि कई मेजबानों पर वितरित किया जा सकता है (यदि आपकी निर्देशिका उदाहरण के लिए साझा की जाती है तो यह फायदेमंद होगा)। समानांतर का उपयोग करते हुए सबसे सरल वाक्यविन्यास होगा:

find . -type f | parallel -j+1 grep mypattern

जहां विकल्प -j+1आपकी मशीन पर कोर की संख्या से अधिक एक प्रक्रिया शुरू करने के लिए समानांतर निर्देश देता है (यह I / O सीमित कार्यों के लिए सहायक हो सकता है, आप संख्या में अधिक जाने की कोशिश भी कर सकते हैं)।

समानांतर में xargsप्रत्येक प्रक्रिया से वास्तव में आउटपुट के क्रम को बनाए रखने और एक सन्निहित उत्पादन उत्पन्न करने पर भी लाभ होता है। उदाहरण के लिए, xargsयदि प्रक्रिया 1 प्रक्रिया लाइन कहती है p1L1, तो प्रक्रिया 2 एक पंक्ति उत्पन्न करती है p2L1, प्रक्रिया 1 दूसरी पंक्ति उत्पन्न करती है p1L2, आउटपुट होगा:

p1L1
p2L1
p1L2

parallelआउटपुट के साथ होना चाहिए:

p1L1
p1L2
p2L1

यह आमतौर पर xargsआउटपुट से अधिक उपयोगी है ।


1
आप शायद के -nसाथ संयोजन में उपयोग करना चाहते हैं -P। अन्यथा, xargsकई प्रक्रियाओं को समाप्त नहीं कर सकता है यदि दो कुछ फाइलें हैं।
स्टीफन चेज़लस

1
खैर, -n1 grepप्रति फ़ाइल एक शुरू होगा । जब तक फाइलें बहुत बड़ी नहीं होती हैं और उनमें से बहुत कम होती हैं, आप शायद यह बढ़ाना चाहते हैं कि थोड़ा सा आप अपना समय शुरू करने और फाइलों को खोजने के बजाय grep प्रक्रियाओं को रोकने में खर्च करेंगे।
स्टीफन चेजलस

9

Grep CPU-वार को तेज करने के कम से कम दो तरीके हैं:

  • यदि आप एक नियमित अभिव्यक्ति के बजाय एक निश्चित स्ट्रिंग की तलाश कर रहे हैं, तो -Fध्वज निर्दिष्ट करें ;

  • यदि आपका पैटर्न ASCII-only है, तो UTF-8 के बजाय 8-बिट लोकेल का उपयोग करें, जैसे LC_ALL=C grep ...

हालांकि यह मदद नहीं करेगा यदि आपकी हार्ड ड्राइव अड़चन है; उस मामले में शायद समानांतर करने से भी मदद नहीं मिलेगी।


1
बस में देखा गया man grep"उदाहरण के रूप में प्रत्यक्ष आहरण या frerep को पदावनत किया जाता है, लेकिन ऐतिहासिक अनुप्रयोगों को अनुमति देने के लिए प्रदान किया जाता है जो उन पर भरोसा करते हैं, जो अनमॉडिफाइड चलाते हैं।" सुनिश्चित नहीं हैं कि यह वास्तव में मायने रखती है, लेकिन रूप में ही हैgrep -F
iyrin

1
जब आप कहते हैं "एक पैटर्न के बजाय" क्या आप एक नियमित अभिव्यक्ति की बात कर रहे हैं?
इयरिन

"ASCII- केवल" खोज बड़े पैमाने पर कम CPU का उपयोग करती है। लेकिन तुम पर चेतावनियां टिप्पणी में उल्लेख किया है पढ़ने की जरूरत है stackoverflow.com/a/11777835/198219
famzah

3

यदि समस्या I / O बाध्य नहीं है तो आप एक ऐसे उपकरण का उपयोग कर सकते हैं जो मल्टी-कोर प्रोसेसिंग के लिए अनुकूलित है।

आप sift ( http://sift-tool.org , अस्वीकरण: मैं इस उपकरण का लेखक हूं) या सिल्वर खोजक ( https://github.com/ggreer/the_silver_searcher ) पर एक नज़र डालना चाहता हूं ।

यदि आप एक regex पैटर्न का उपयोग करते हैं और एक स्पिम्पल स्ट्रिंग खोज का उपयोग नहीं करते हैं, तो चांदी खोजकर्ता की फ़ाइल आकार सीमा 2GB है।


निश्चित रूप से फाइलों का एक गुच्छा खोज एक समस्या का एक उत्कृष्ट उदाहरण है जो IO बाध्य है?
जोनाथन हार्टले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.