2008-11-20 8 views

उत्तर

109

एक अनुदेश कई प्रक्रियाओं और पाइप के इनपुट में एक प्रक्रिया के उत्पादन के रूप में चलाने के लिए पाइप प्रतीक की व्याख्या की नौकरी एक और प्रक्रिया खोल की ज़िम्मेदारी है (/ बिन/श या समकक्ष)।

अपने उदाहरण में तुम इतनी तरह पाइपिंग प्रदर्शन करने के लिए अपने शीर्ष स्तर खोल उपयोग करने के लिए चुन सकते हैं:

find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep' 

दक्षता के मामले में यह लागत परिणाम मिल जाए, zcat के कई आमंत्रण में से एक मंगलाचरण, और एक agrep का आविष्कार।

यह केवल एक ही agrep प्रक्रिया पैदा की जा रही है जो सभी उत्पादन zcat के कई आमंत्रण द्वारा उत्पादित की प्रक्रिया होगी जाएगी।

किसी कारण से आप agrep कई बार आह्वान करने के लिए चाहते हैं, तो आप कर सकते हैं:

find . -name 'file_*' -follow -type f \ 
    -printf "zcat %p | agrep -dEOE 'grep'\n" | sh 

यह पाइप का उपयोग कर निष्पादित करने के लिए आदेशों की एक सूची का निर्माण करती है, तो एक नया खोल करने के लिए इन भेजता है वास्तव में निष्पादित किया जाना है । (अंतिम "| sh" को ओमटिंग करना इस तरह कमांड लाइनों के सूखे रनों को डीबग करने या निष्पादित करने का एक अच्छा तरीका है।)

दक्षता के मामले में इस परिणाम में खोज का एक आमंत्रण, sh का एक आमंत्रण, जेडटी के कई आमंत्रण और agrep के कई invocations।

find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep' 

... जो लगता है में से एक मंगलाचरण, xargs में से एक मंगलाचरण, zcat के कुछ ही आमंत्रण और लागत:

आदेश आमंत्रण की संख्या के मामले में सबसे कारगर समाधान पॉल Tomblin से सुझाव है agrep का एक आविष्कार।

+1

xargs का एक अन्य लाभ होगा, कि आप इसे -पी स्विच (-P 0) का उपयोग कर आधुनिक बहु कोर सीपीयू के साथ और भी अधिक गति दे सकते हैं। – flolo

+0

हां, -पी स्विच वास्तव में सामान्य रूप से निष्पादन को गति देने का एक अच्छा तरीका है। दुर्भाग्यवश, आप agrep interleaved में पाइप किए जाने वाले समानांतर जेकैट प्रक्रियाओं के आउटपुट का जोखिम चलाते हैं, जो परिणाम को प्रभावित करेगा। इस प्रभाव का उपयोग करके प्रदर्शित किया जा सकता है: echo -e "1 \ n2" | xargs -P 0 -n 1 yes | uniq –

+0

@Adam, मैंने आपका सुझाव दिया है। –

13
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep' 
+0

दक्षता कारणों के लिए प्रिंट और xargs से बचने के लिए आशा का आनंद जानता है। हो सकता है कि यह वास्तव में मेरी समस्या है: पाइप किए गए कमांड को -exec – someguy

+0

के माध्यम से नहीं ढूंढ सकता है यह उनके नामों में रिक्त स्थान वाली फ़ाइलों के साथ काम नहीं करता है; ठीक करने के लिए, प्रिंट करें -प्रिंट 0 के साथ प्रिंट करें और -0 विकल्प को xargs –

+2

@someguy - Wha में जोड़ें? दक्षता कारणों से xargs से बचें? जेकैट के एक उदाहरण को कॉल करना, और इसे एकाधिक फाइलों की एक सूची पास करना, प्रत्येक मिली फ़ाइल के लिए इसके नए उदाहरण को निष्पादित करने से * अधिक * अधिक कुशल है। –

190

समाधान आसान है: श के माध्यम से निष्पादित

... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \; 
+13

क्या ओपी पूरा करने की कोशिश कर रहा था ऊपर दिए गए सुझावों से मुलाकात की जा सकती है, लेकिन यह वह है जो वास्तव में पूछे गए प्रश्न का उत्तर देता है। इस तरह से ऐसा करने के कारण हैं - निष्पादन द्वारा लौटाई गई फ़ाइलों पर काम करने से निष्पादन बहुत अधिक शक्तिशाली है, खासकर जब परीक्षण के साथ मिलकर। उदाहरण के लिए: geda-gaf/-type d -exec bash -c 'DIR = {}; [[$ ($ DIR -maxdepth 1 | xargs grep -i मसाला | wc -l) -ge 5]] && $ dIR echo \;; खोज पथ में सभी निर्देशिकाएं लौटाएंगी जिनमें मसाला – swarfrat

+2

शब्द युक्त सभी निर्देशिकाओं में कुल 5 लाइनें शामिल हैं। पूरे आउटपुट को grepping (जैसा कि अन्य उत्तरों सुझाव) प्रत्येक फ़ाइल grep के समान नहीं है। युक्ति: sh के बजाय, आप जो भी अन्य खोल चाहते हैं उसका उपयोग कर सकते हैं (मैंने कोशिश की है कि बैश के साथ और यह ठीक चल रहा है)। – pagliuca

+1

सुनिश्चित करें कि '-c' विकल्प को नजरअंदाज न करें। अन्यथा आपको एक परेशानी 'ऐसी कोई फ़ाइल या निर्देशिका' त्रुटि संदेश नहीं मिलेगा। – asmaier

8

आप while लूप पर भी पाइप कर सकते हैं जो फ़ाइल पर कई क्रियाएं कर सकता है जो find रेखांकित करता है। तो यहाँ jar फ़ाइलों

find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done 

प्रमुख मुद्दा जा रहा है कि while पाश संदर्भित फ़ाइल के द्वारा अलग नाम में पारित कई आदेशों में शामिल है की एक बड़ी distro के साथ फ़ोल्डर में एक दिया जावा वर्ग फ़ाइल के लिए jar अभिलेखागार में तलाश के लिए एक है अर्धविराम और इन आदेशों में पाइप शामिल हो सकते हैं। तो उस उदाहरण में मैं मिलान करने वाली फ़ाइल के नाम को प्रतिबिंबित करता हूं, फिर दिए गए वर्ग नाम के लिए संग्रह फ़िल्टरिंग में क्या सूचीबद्ध करता है।

/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core: उत्पादन की तरह दिखता है .databinding.observable_1.2.0.M20090902-0800.jar org/ग्रहण/कोर/डेटा बाइंडिंग/नमूदार/सूची/IObservableList .class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1। r351_v20090708-0800.jar /usr/lib/eclipse/plugins/org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300।/usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar जार /usr/lib/eclipse/plugins/org.eclipse.help.appserver_3.1.400.v20090429_1800.jar

मेरे बैश खोल में (xubuntu10.04/xfce) यह वास्तव में मिलान किए गए वर्गनाम को fgrep मिलान किए गए स्ट्रिंग को हाइलाइट करता है; यह सैकड़ों jar फ़ाइलों की सूची को स्कैन करना वास्तव में आसान बनाता है जो खोजे गए थे और आसानी से किसी भी मैच को देख सकते थे।

खिड़कियों आप के साथ एक ही बात कर सकते हैं पर: कि कि खिड़कियों पर में आदेश विभाजक है '&' नहीं

for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList 

टिप्पणी ';' और यह कि '@' लिनक्स को उपरोक्त आउटपुट खोजने की तरह एक साफ आउटपुट देने के लिए कमांड की गूंज को दबा देता है; हालांकि findstr मिलान किए गए स्ट्रिंग को बोल्ड नहीं बना रहा है, इसलिए आपको मिलान किए गए वर्ग के नाम को देखने के लिए आउटपुट पर थोड़ा करीब देखना होगा। ऐसा लगता है कि आदेश 'के लिए' खिड़कियां इस तरह के पाठ फ़ाइलों के माध्यम से पाशन के रूप में काफी कुछ चाल ...

संबंधित मुद्दे