युगल हजारों फ़ाइलों में Grep


13

मेरे पास cca 26 000 फाइलों के साथ डायरेक्टरी है और मुझे इन सभी फाइलों को grep करने की आवश्यकता है। समस्या यह है कि, मुझे इसकी जितनी जल्दी हो सके आवश्यकता है, इसलिए यह स्क्रिप्ट बनाने के लिए आदर्श नहीं है जहां grep कमांड खोजने के लिए एक फ़ाइल का नाम लेगा और मैच फाइल करने के लिए लिख देगा। "तर्कों की सूची बहुत लंबी" जारी करने से पहले इस सभी फाइलों में grep को cca 2 मिनट का समय लगा। किसी भी विचार यह कैसे करना है? संपादित करें: एक स्क्रिप्ट है जो हर समय नई फाइलें बना रही है, इसलिए सभी फाइलों को अलग-अलग अवधि में रखना संभव नहीं है।


1
के findसाथ xargsया उपयोगgrep -R
Eddy_Em

यह अच्छा काम करता है, लेकिन इसमें 10 मिनट लगते हैं ...
user2778979

जवाबों:


19

के साथ find:

cd /the/dir
find . -type f -exec grep pattern {} +

( -type fकेवल नियमित फ़ाइलों में खोज करना है (यदि वे नियमित फ़ाइलों की ओर इशारा करते हुए भी सहानुभूति को छोड़कर हैं)। यदि आप निर्देशिकाओं को छोड़कर किसी भी प्रकार की फ़ाइल में खोज करना चाहते हैं (लेकिन सावधान रहें कुछ प्रकार की फाइलें जैसे डेटो या देव / शून्य हैं) आप आम तौर पर पढ़ना नहीं चाहते), -type fGNU- विशिष्ट के साथ बदलें ! -xtype d( सिम्लिंक रिज़ॉल्यूशन के बाद -xtype dटाइप डायरेक्टरी की फ़ाइलों के लिए मिलान )।

GNU के साथ grep:

grep -r pattern /the/dir

(लेकिन खबरदार कि जब तक आपके पास GNU grep का हालिया संस्करण नहीं है, तब तक यह निर्देशिका में उतरते समय सहानुभूति का पालन करेगा)। जब तक आप कोई -D readविकल्प नहीं जोड़ते, तब तक गैर-नियमित फ़ाइलों की खोज नहीं की जाएगी । GNU के हाल के संस्करण grepअभी भी सिम्बलिंक के अंदर नहीं खोजेंगे।

जीएनयू के बहुत पुराने संस्करणों findने मानक {} +वाक्यविन्यास का समर्थन नहीं किया , लेकिन वहां आप गैर-मानक का उपयोग कर सकते हैं:

cd /the/dir &&
  find . -type f -print0 | xargs -r0 grep pattern

प्रदर्शन I / O बाध्य होने की संभावना है। यह खोज करने का समय है, भंडारण से उस सभी डेटा को पढ़ने के लिए आवश्यक समय होगा।

यदि डेटा एक निरर्थक डिस्क सरणी पर है, तो एक बार में कई फ़ाइलों को पढ़ने से प्रदर्शन में सुधार हो सकता है (और अन्यथा उन्हें नीचा दिखा सकता है)। यदि प्रदर्शन I / O बाध्य नहीं हैं (क्योंकि उदाहरण के लिए सभी डेटा कैश में है), और आपके पास कई CPU हैं, तो समवर्ती grepsभी मदद कर सकता है। आप ऐसा जीएनयू xargsके -Pविकल्प के साथ कर सकते हैं ।

उदाहरण के लिए, यदि डेटा 3 ड्राइव के साथ RAID1 सरणी पर है, या यदि डेटा कैश में है और आपके पास 3 सीपीयू हैं जिनका समय समाप्त हो गया है:

cd /the/dir &&
  find . -type f -print0 | xargs -n1000 -r0P3 grep pattern

(यहां -n1000एक नई grepहर 1000 फ़ाइलों को एक समय में समानांतर में चलने वाली 3 तक का उपयोग करने के लिए )।

हालाँकि, ध्यान दें कि यदि आउटपुट grepको पुनर्निर्देशित किया जाता है, तो आप 3 grepप्रक्रियाओं से बुरी तरह से इंटरलेव्ड आउटपुट के साथ समाप्त हो जाएंगे , जिस स्थिति में आप इसे चलाना चाहते हैं:

find . -type f -print0 | stdbuf -oL xargs -n1000 -r0P3 grep pattern

(एक हालिया GNU या FreeBSD सिस्टम पर) या --line-bufferedGNU के विकल्प का उपयोग करें grep

यदि patternएक निश्चित स्ट्रिंग है, तो -Fविकल्प जोड़ने से मामलों में सुधार हो सकता है।

यदि यह मल्टी-बाइट कैरेक्टर डेटा नहीं है, या यदि उस पैटर्न के मिलान के लिए, तो इससे कोई फर्क नहीं पड़ता कि डेटा मल्टी-बाइट कैरेक्टर है या नहीं, फिर:

cd /the/dir &&
  LC_ALL=C grep -r pattern .

प्रदर्शन में काफी सुधार कर सकता है।

यदि आप अक्सर ऐसी खोज करते हैं, तो आप अपने डेटा को कई खोज इंजनों में से किसी एक का उपयोग करके अनुक्रमित करना चाहते हैं।


3

एक ही डायरेक्टरी में 26000 फाइलें ज्यादातर फाइल सिस्टम के लिए बहुत कुछ है। यह संभावना है कि इस बड़ी निर्देशिका को पढ़ने में समय का एक महत्वपूर्ण हिस्सा लिया जाए। इसे केवल कुछ सौ फाइलों के साथ छोटी निर्देशिकाओं में विभाजित करने पर विचार करें।

findजब तक आप इसे गलत नहीं करते कॉलिंग खराब प्रदर्शन की व्याख्या नहीं कर सकती। यह एक निर्देशिका का पता लगाने का एक तेज़ तरीका है, और यह सुनिश्चित करने के लिए कि आप एक कमांड लाइन को निष्पादित करने का प्रयास नहीं करते हैं जो बहुत लंबा है। सुनिश्चित करें कि आप उपयोग करते हैं -exec grep PATTERN {} +, जो कि आदेश के अनुसार कई फ़ाइलों को पैक कर सकता है, और न ही -exec grep PATTERN {} \;, जो grepप्रति फ़ाइल एक बार निष्पादित करता है: एक बार प्रति फ़ाइल कमांड को निष्पादित करना काफी धीमा होने की संभावना है।


धन्यवाद, मैं इसके बारे में कुछ बताऊंगा और शायद मैं इसे अलग कर दूंगा। मैंने ठीक वही बनाया है जिसके बारे में आप लिख रहे हैं और यह केवल grep की तुलना में 3 गुना लंबा है ...
user2778979

गाइल्स, क्या आप कह रहे हैं कि प्रदर्शन एक निर्देशिका में 26,000 फ़ाइलों के लिए काफी भिन्न होगा।
user001

1
@ user001 हाँ। वे कितना भिन्न होते हैं यह फाइलसिस्टम पर और संभवतः अंतर्निहित स्टोरेज पर निर्भर करता है, लेकिन मैं किसी भी फाइल सिस्टम से यह उम्मीद करूंगा कि एक निर्देशिका में 26000 फाइलों की तुलना में 100 निर्देशिकाओं में से 260 फाइलों के साथ औसत रूप से तेज हो।
गिलेस एसओ- बुराई को रोकना '

स्पष्टीकरण के लिए धन्यवाद। मैंने विसंगति के आधार को समझने के लिए इस बिंदु पर एक अनुवर्ती प्रश्न पूछा ।
user001

0

यदि आपको कई बार सभी फ़ाइलों को grep करने की आवश्यकता है (जैसा कि आपने कहा, एक स्क्रिप्ट चल रहा है) मैं सुझाव दूंगा कि RAM डिस्क, वहां सभी फ़ाइलों को कॉपी करें और फिर फ़ाइलों को कई बार grep करें, इससे आपकी खोज को एक कारक द्वारा गति मिलेगी कम से कम 100x।

बस आपको पर्याप्त राम चाहिए। और, आपको फाइलों को अनुक्रमित करना चाहिए, जैसे। ल्यूसिन या नोसक्ल डेटाबेस में और फिर उस पर चल रहे प्रश्न।


जैसा कि कहीं और उल्लेख किया गया है, यह इस तथ्य की मदद नहीं करता है कि एक grepखिलाफ चलाने के लिए बहुत सारी फाइलें हैं । इस बिंदु पर भी है कि: "एक स्क्रिप्ट है जो हर समय नई फाइलें बना रही है, इसलिए सभी फाइलों को अलग-अलग फाइलों में रखना संभव नहीं है।"
जेफ स्कालर

-2

निर्देशिका में सभी फ़ाइलें

grep 'search string' *

पुनरावर्ती के साथ

grep -R 'search string' *

देखभाल करने के लिए विस्तृत -1?
मार्कस

4
मैं नीचे नहीं गया, लेकिन आपके साथ कुछ समस्याएँ हैं: ओपी ने "अरग लिस्ट बहुत लंबी" का उल्लेख किया है, जो कि आपके पहले वाले को ठीक नहीं करेगा और शायद वही होगा जो ओपी पहले कर रहा था। दूसरा कोई भी उस संबंध में मदद नहीं करता है (आपने .इसके बजाय इसका इस्तेमाल किया होगा *)। *डॉट फ़ाइलों को बाहर कर देगा (हालांकि, -R के साथ, रिकर्स्ड निर्देशिकाओं में नहीं)। -R के विरोध के रूप में -r GNU grep के हाल के संस्करणों के साथ भी सहानुभूति का अनुसरण करता है। आपके पास वर्तमान निर्देशिका में फ़ाइलों के साथ एक समस्या होगी जिसका नाम इसके साथ शुरू होता है-
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.