मैं कैसे -EXEC और अभी भी एक फाइल करने के लिए उत्पादन का उपयोग कर के परिणाम grep कर सकते हैं?


64

उदाहरणों पर समझाने के लिए बेहतर है।

मैं निम्न्लिखित कर सकता हूँ:

find . -name "*.py" -type f > output.txt

लेकिन मैं आउटपुट को उसी फ़ाइल के लिए कैसे संग्रहीत कर सकता हूं:

find . -name "*.py" -type f -exec grep "something" {} \

मैं बस नहीं कर सकता

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt

जवाबों:


105

अगर मैं तुम्हें सही ढंग से समझूं कि तुम क्या करना चाहते हो:

find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt

Findएक्सटेंशन वाली सभी फाइलें py, grepकेवल पंक्तियाँ होती हैं somethingऔर पंक्तियों को सहेजती हैं output.txt। यदि फ़ाइल में कुछ भी है तो उसे बदल दिया जाएगा।

संपादित करें: प्रयोग -सेक्स:

find . -name '*.py' -exec grep 'something' {} \; > output.txt

मैं यहाँ क्रिस डाउन्स टिप्पणी शामिल कर रहा हूँ। उपरोक्त आदेश के परिणामस्वरूप grepकई बार निष्पादित होने के रूप में निष्पादित किया जाएगा find। हालांकि, अगर आप की जगह ;एक साथ +, grepसे उत्पादन के साथ कहा जाता है findconcatenated (ऊपर एक निश्चित सीमा)। विषय पर अधिक खोजने के लिए निष्पादन के साथ अर्धविराम (;) बनाम प्लस (+) का उपयोग करके प्रश्न देखें ।


16
+इसके बजाय का उपयोग करें \;, यह निष्पादन के समय में काफी सुधार करेगा (क्योंकि यह निष्पादन से पहले तक के तर्कों का खंडन करेगा ARG_MAX)।
क्रिस डाउन

अब मैं xargs की शक्ति को समझता हूं! धन्यवाद!
डोमिह

4
grep -Hयदि आप फ़ाइल का फ़ाइल नाम आउटपुट में शामिल करना चाहते हैं तो इसका उपयोग करें ।
स्टाइनर

18

यदि आप सभी फाइलों में सभी मिलान लाइनों को सहेजना चाहते हैं output.txt, तो आपकी अंतिम कमांड काम करती है, सिवाय इसके कि आप ;कमांड के अंत में आवश्यक याद कर रहे हैं ।

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt

यदि आप चाहते हैं कि प्रत्येक रन grepएक अलग फ़ाइल में आउटपुट का उत्पादन करे, आउटपुट फ़ाइल नाम की गणना करने और पुनर्निर्देशन करने के लिए एक शेल चलाएं।

find . -name "*.py" -type f -exec sh -c 'grep "something" <"$0" >"$0.txt"' {} \;

अंतिम एक बहुत अच्छा: D
bakytn

@Gilles उत्तर पर इसे और अधिक जानकारीपूर्ण बनाने के लिए विस्तार करने के लिए, खासकर यदि आप जिन फ़ाइलों के साथ काम कर रहे हैं, उनकी सूची बड़ी है, तो आप इसका उपयोग करके grep'ed परिणामों के साथ प्रत्येक फ़ाइल के फ़ाइल नाम (सापेक्ष पथ) की रिपोर्ट कर सकते हैं : find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt और अगर आप grep'ed लाइनों की लाइन नंबर देखना चाहते हैं, तो बेशक, उपयोग करेंgrep -n "something"
JJMpls

9

रिकॉर्ड के लिए, आपके grepपास मौजूद फ़ाइलों को फ़िल्टर करने के लिए उपयोग किए जाने वाले तर्क --includeऔर --excludeतर्क हैं:

grep -r --include="*.py" "something" > output.txt

2
कम से कम जीएनयू grepकरता है।
phk

2

उपयोग करें tee:

find . -name '*.py' | tee output.txt | xargs grep 'something'

चेतावनी, आप (रिक्त स्थानों सहित) विशेष वर्ण के साथ किसी भी फाइल है, तो यह है कि xargsऔर grepके साथ अच्छी तरह से काम नहीं करेगा ( a file.txtदो फ़ाइलों के रूप में व्याख्या की जाएगी, aऔर file.txt)। इसका विकल्प -xया तो उपयोग करना है या फिर -print0, लेकिन इनमें से कोई भी आपके प्रदूषण को कम करेगा output.txt-xका उपयोग करेगा \कुछ विशेष वर्ण से बचने के लिए करते हैं और इस में हो जाएगा output.txt-print0एक क्षेत्र विभाजक के रूप में एक अशक्त बाइट का उपयोग करेगा (जो भी जरूरी है xargs -0) और output.txtपाठ की एक लंबे समय से सटे लाइन की तरह दिखाई देगा।

आप इससे कैसे निपटते हैं (या नहीं) यह आप पर निर्भर है।

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