पाइप grep -v में मिलते हैं


18

मैं उन सभी फाइलों को खोजने की कोशिश कर रहा हूं जो एक निश्चित प्रकार की हैं और उनमें एक निश्चित स्ट्रिंग नहीं है। मैं grep -v को पाइपिंग खोज कर इसके बारे में जाने की कोशिश कर रहा हूं

उदाहरण:

find -type f -name '*.java' | xargs grep -v "something something"

इससे काम नहीं लगता है। यह केवल उन सभी फाइलों को वापस लौटाने के लिए लगता है जो खोज आदेश मिला। मैं जो करने की कोशिश कर रहा हूं वह मूल रूप से सभी .java फाइलें हैं जो एक निश्चित फ़ाइल नाम से मेल खाती हैं (जैसे 'Pb' के साथ SessionPb.java में समाप्त होती हैं) और इसके अंदर एक 'एक्सटेंड समथिंगसमैन' नहीं है।

मेरा संदेह यह है कि मैं इसे गलत कर रहा हूं। तो इसके बजाय कमांड कैसे दिखना चाहिए?


आप जोड़ सकते हैं कि आपको क्या लगता है कि यह काम नहीं किया। शायद आपकी grep अभिव्यक्ति बहुत स्पष्ट है? मामले में असंवेदनशीलता के लिए '-i' की जरूरत है? मेरा जवाब नीचे भी देखें ...
lornix

जवाबों:


21

यहां कोई जरूरत नहीं xargsहै। इसके अलावा, आपको विकल्प (मैच के बिना फाइलें) के grepसाथ उपयोग करने की आवश्यकता है -L, अन्यथा यह आपके नाम के बजाय फ़ाइल सामग्री को आउटपुट करेगा, जैसे आपके उदाहरण में।

find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+

1
-Lपहले से ही बातचीत है, क्योंकि इसका मतलब है files _without_ match। इसलिए आपको -vयहां विकल्प की आवश्यकता नहीं है।
भीड़

3
अंत में अतिरिक्त + के साथ नहीं।
lynxlynxlynx

2
@ user946850 हर बार जब मैं find -exec \+लिखता हूं तो कोई मुझे लिखता है कि यह xargs का उपयोग करना बेहतर है। टिप्पणी लिखने से पहले कोई भी आदमी क्यों नहीं दिखता है? (:
भीड़

5
@ user946850 के -exec ... {} \+बराबर नहीं है xargs। कृपया पढने के दस्तावेज ढूंढे! (मैंने इस पर काफी मेहनत की!)
जेम्स यंगमैन

2
@ user946850 हाँ। एक अंतर यह है कि (डिफ़ॉल्ट रूप से) xargsइसके इनपुट को संसाधित करता है और सफेद स्थान पर तर्क को अलग करता है। उद्धरण भी विशेष (डिफ़ॉल्ट रूप से) हैं xargs। इनमें से किसी भी चीज के लिए सच नहीं है -exec ... {} +। पुराने संस्करणों का xargsउपयोग एक EOF संकेतक के रूप में अंडरस्कोर पर विचार करने के लिए किया जाता है, लेकिन यह कोई और मामला नहीं है।
जेम्स यंगमैन

7

आप वास्तव में लगभग मिल गया है ...

find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something"

बिन्दु '।' यहाँ से शुरू करने के लिए कहते हैं। (तुम्हारा मतलब है .. लेकिन कभी नहीं मान)।

-iname केस-असंवेदनशील खोज का उपयोग करता है, बस मामले में (या सिर्फ-केस में नहीं)।
-print0 को एक अनुगामी \ x00 वर्ण के साथ xargs में भेजता है, जो फ़ाइल नाम में रिक्त स्थान होने के साथ समस्याओं को रोकता है।

xargs पर '-0' रिटर्न के बजाय फ़ाइल नाम के \ x00 के साथ समाप्त होने की अपेक्षा करता है।

और आपके grep कमांड ...

बहुत ज्यादा मिला।


संपादित ::

आपके अपडेट से:

find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something"

मदद करनी चाहिए। (जोड़ा गया @ @ भीड़ के जवाब से, अच्छी नौकरी)

मुझे यह विचार है कि आपके grep को '-i' विकल्प की आवश्यकता है, या कम स्पष्ट होने के लिए।

भागों में कमांड का प्रयास करें ... क्या यह उत्पादन फ़ाइल नाम उचित लगता है?

find . -type f -iname "*pb.java"

यदि ऐसा है, तो आपकी समस्या की संभावना है या तो आपका grep खोज पैटर्न मेल नहीं खा रहा है (वर्तनी की त्रुटि? यह होता है!), या अभी कोई मैच नहीं हैं।

सबसे खराब स्थिति:

grep -riL "something" *

सब कुछ खोज करने के लिए बहुत अधिक काम करेगा, लेकिन आपको कुछ आउटपुट देना चाहिए।


मैंने आपके संशोधनों की कोशिश की और मुझे अभी भी वह परिणाम नहीं मिल रहा है जिसकी मुझे उम्मीद है। मैं इसे स्पष्ट करने के लिए प्रश्न को अपडेट करने का प्रयास करूंगा।
१०:१४ पर Hyangelo

यदि प्रश्न का लेखक सिर्फ फ़ाइल नाम ढूंढना चाहता है, तो क्या grep 'grep -l -v' नहीं होना चाहिए?
ब्रूस एडगर जूल

वह *
.java

xargs -0 grep -v "something something"xargs -0 grep -v "something something" /dev/nullअन्यथा होना चाहिए जब आप कोई मिलान फ़ाइलों का पता लगाने के लिए विषम परिणाम प्राप्त करेंगे।
जेम्स यंगमैन

{मुस्कराहट} हाँ, कहीं न कहीं लॉजिक सभी बालों वाला था। अपने सिर को चोट पहुंचाने के लिए एक उलटा झूठा लॉजिक मल्टीपल टेस्ट जैसा कुछ भी नहीं।
lornix

4

कंप्यूटर एक कंप्यूटर हो रहा है: यह वही कर रहा है जो आपने इसे करने के लिए कहा था कि आप इसे क्या करना चाहते थे।

grep -v "something something"सभी पंक्तियों को प्रिंट करता है, जिसमें शामिल नहीं है something something। उदाहरण के लिए, यह निम्नलिखित तीन में से दो पंक्तियों को प्रिंट करता है:

hello world
this is something something
something else

उन फ़ाइलों को प्रिंट करने के लिए जिनमें extends SomethingSomethingकहीं भी नहीं है , -Lविकल्प का उपयोग करें :

grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…

Grep के कुछ संस्करणों में -Lविकल्प नहीं है (यह POSIX द्वारा निर्दिष्ट नहीं है )। यदि आपका नहीं है, तो इसका कुछ भी प्रिंट नहीं है, और रिटर्न कोड का उपयोग कॉलिंग शेल को करने के लिए करें जो इसके बजाय करना चाहिए।

grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME ||
echo "$FILENAME"

वैकल्पिक रूप से, awk का उपयोग करें।

awk '
    FNR == 1 && NR != 1 && !found { print fn }
    FNR == 1 { fn = FILENAME; found = 0; }
    /extends[[:space:]]+SomethingSomething/ { found = 1 }
    END { if (fn != "" && !found) print fn }
'

Linux या Cygwin (या GNU grep के साथ अन्य प्रणाली) पर, आपको उपयोग करने की आवश्यकता नहीं है find, जैसा grepकि पुनरावृत्ति करने में सक्षम है।

grep -R --include='*.java' -L -E 'extends[[:space:]]+SomethingSomething'

यदि आपका खोल ksh या bash या zsh है, तो आप शेल को फ़ाइल नाम मिलान कर सकते हैं। बैश पर, set -o globstarपहले चलाएं (आप इसे अपने में डाल सकते हैं ~/.bashrc)।

grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.java

वाह ये तो और भी अच्छा है। मैं 'एक्सटेंड्स (एस) + समथिंग सेलिंग' का उपयोग कर रहा था, जो मुझे बता सकता था कि जहां तक ​​काम करता है। विस्तारित RegEx संस्करण में निर्दिष्ट एक के साथ इस सिंटैक्स के साथ कोई अंतर है?
१२:०२ पर Hyangelo

@ हयांगेलो \sएक GNU grep एक्सटेंशन है, जो मुझे लगता है कि इसका पर्याय है [[:space:]]
गिल्स एसओ- बुराई को रोकना '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.