2008-10-09 19 views
6

मुझे कई बार निर्देशिकाओं के साथ काम करना पड़ता है जिसमें सैकड़ों हजारों फाइलें हैं, टेक्स्ट मिलान करना, प्रतिस्थापित करना आदि। मैं के मानक तरीका अपनाते हैं, कहते हैं किबैश में काम करते समय आप "बहुत सारी फाइलें" समस्या को कैसे संभालेंगे?

grep foo * 

अगर मैं बहुत सारी फ़ाइलें त्रुटि संदेश मिलता है, तो मैं

for i in *; do grep foo $i; done 

या

find ../path/ | xargs -I{} grep foo "{}" 

कर अंत लेकिन इन से कम हैं इष्टतम (प्रत्येक फ़ाइल के लिए एक नई grep प्रक्रिया बनाएँ)।

यह तर्क कार्यक्रमों के आकार में एक सीमा की तरह दिखता है, क्योंकि * लूप में * ठीक काम करता है। लेकिन, किसी भी मामले में, इसे संभालने का उचित तरीका क्या है?

पीएस: मुझे grep -r करने के लिए मत कहो, मुझे इसके बारे में पता है, मैं उन उपकरणों के बारे में सोच रहा हूं जिनके पास रिकर्सिव विकल्प नहीं है।

उत्तर

8

findutils के नए संस्करण में, कर सकते हैं लगता है xargs का काम (glomming व्यवहार सहित, ऐसा है कि केवल के रूप में कई ग्रेप प्रक्रियाओं रूप में की जरूरत उपयोग किया जाता है):

find ../path -exec grep foo '{}' + 

पिछले तर्क के रूप में + बजाय ; के उपयोग के इस व्यवहार से चलाता है।

+0

ग्रेट टिप! मैं कभी भी "+" विकल्प के बारे में नहीं जानता था। – mhawke

4

xargs प्रत्येक फ़ाइल के लिए एक नई प्रक्रिया शुरू नहीं करता है। यह तर्कों को एक साथ जोड़ता है। Xargs के विकल्प के लिए एक नज़र डालें - यह सब-कमांड के प्रत्येक निष्पादन को पारित तर्कों की संख्या को नियंत्रित करता है।

+0

जैसा कि Ry4an ने xargs का उपयोग करके उल्लेख किया है- मैं बैचिंग बंद कर देता हूं। – ephemient

+0

'xargs -n' –

0

मैं नहीं देख सकते हैं कि

for i in *; do 
    grep foo $i 
done 

काम करेगा के बाद से मैंने सोचा था कि "बहुत सारी फ़ाइलें" एक कवच की सीमा थी, इसलिए यह रूप में अच्छी तरह पाश के लिए के लिए विफल हो जाएगा।

कहा करने के बाद कि, मैं हमेशा xargs प्रबंधनीय बिट्स में तर्क सूची बंटवारे इस प्रकार की घुरघुराना काम करते हैं:

find ../path/ | xargs grep foo 

यह फ़ाइल प्रति लेकिन प्रति फ़ाइलों के समूह की प्रक्रिया शुरू नहीं होंगे।

+0

के लिए उपरोक्त नहीं," बहुत अधिक फ़ाइलें "सीमा है क्योंकि प्रोग्राम को निष्पादित किए जाने वाले तर्कों की लंबाई आकार में प्रतिबंधित है। "मैं में * * किसी अन्य प्रोग्राम को निष्पादित करने के लिए वर्तमान खोल को कभी नहीं छोड़ता, इसलिए यह इस सीमा को हिट नहीं कर सकता है। – ephemient

+0

उपर्युक्त टिप्पणी पर प्रतिबिंबित करने और विस्तार करने के लिए - यह किसी भी प्रक्रिया आमंत्रण के लिए संयुक्त पर्यावरण परिवर्तनीय और argv स्पेस पर एक सीमा है, शेल सीमा नहीं। ग्लोब विस्तार 'मेमोरी आवंटन ढेर से निकलते हैं - वे इसके अधीन नहीं होते हैं - जब तक कि आप अपने परिणामों को बाहरी कमांड की कमांड लाइन पर या पर्यावरण चर में नहीं डालते (शैल वैरिएबल को पर्यावरण में निर्यात नहीं किया जाता है अभी भी ढेर हैं, इस प्रकार ठीक है)। –

6

अगर कोई रिक्त स्थान युक्त फ़ाइल नामों का खतरा है, तो आप xargs को -0 ध्वज के साथ एक साथ -print0 झंडा उपयोग करने के लिए खोजने के लिए याद रखना चाहिए:

find . -print0 | xargs -0 grep -H foo 
+0

मैं आमतौर पर विभाजक के रूप में न्यूलाइन का उपयोग करके 'xargs -d' \ n'' का उपयोग करता हूं, क्योंकि डिफ़ॉल्ट रूप से न्यूलाइन द्वारा अलग किए गए पथ आउटपुट पथ ढूंढते हैं। – ephemient

+0

@ephemient, यह असुरक्षित है, क्योंकि POSIX फाइल सिस्टम फ़ाइल नामों के भीतर न्यूलाइन की अनुमति देता है। –

+0

किस तरह से असुरक्षित? हां, एक संभावना है कि grep कुछ फ़ाइल नामों पर असफल हो जाएगा, लेकिन जब तक grep में कोई सुरक्षा छेद न हो, तो यह असुरक्षित कैसे है? – JesperE

0

ठीक है, मुझे भी यही समस्याएं थीं, लेकिन ऐसा लगता है कि मेरे साथ आने वाली सभी चीज़ों का पहले से ही उल्लेख किया गया है। ज्यादातर, दो समस्याएं थीं। ग्लोब करना महंगा है, एक लाख फाइल निर्देशिका पर ls करना हमेशा के लिए (मेरे सर्वरों में से एक पर 20+ मिनट) लेता है और एक लाख फाइल निर्देशिका पर ls * हमेशा के लिए लेता है और "तर्क सूची बहुत लंबी" त्रुटि के साथ विफल रहता है।

find /some -type f -exec some command {} \; 

दोनों समस्याओं के साथ मदद करने लगता है। साथ ही, यदि आपको इन फ़ाइलों पर अधिक जटिल संचालन करने की आवश्यकता है, तो आप अपनी सामग्री को कई धागे में स्क्रिप्ट करने पर विचार कर सकते हैं। सीएलआई सामान स्क्रिप्टिंग के लिए यहां एक अजगर प्राइमर है। http://www.ibm.com/developerworks/aix/library/au-pythocli/?ca=dgr-lnxw06pythonunixtool&S_TACT=105AGX59&S_CMP=GR

+0

खोज -exec grep foo ';' का उपयोग करना मूल समाधान के समान समस्या है जिसमें यह प्रत्येक फ़ाइल के लिए grep का एक व्यक्तिगत उदाहरण निष्पादित करता है। –