लिनक्स में एक साथ दो तार वाली फाइलें कैसे खोजें?


11

मैं एक साथ दो तार वाली फाइलें ढूंढना चाहता हूं, उदाहरण के लिए फाइल में दोनों string1और हैं string2

मैं आउटपुट में फ़ाइलों का पूर्ण पथ चाहता हूं। मैं "अनुमति से इनकार" चेतावनियाँ नहीं देखना चाहता।

जवाबों:


15
grep -l string2 `grep -l string1 /path/*`

जो जैसा है वैसा है

grep -l string2 $(grep -l string1 /path/*)

संपादित करें: grep string1 /path/* | grep string2विधर्मियां ऐसा क्यों नहीं करती हैं जो मुझे लगता है कि alwbtc चाहता है।

$ cd /tmp
$ cat a
apples
oranges
bananas
$ cat b
apples
mangoes
lemons
$ cat c
mangoes
limes
pears
$ cd ~
$ grep apples /tmp/* | grep mangoes
$

कुछ भी नहीं मिला, लेकिन फ़ाइल बी में दोनों तार हैं।

यहाँ मुझे लगता है कि alwbtc क्या चाहता है

$ grep -l apples $(grep -l mangoes /tmp/*)
/tmp/b

1
यह एक साफ समाधान है और खदान से अधिक उपयोगी है। उन लोगों के लिए जो जानना चाहते हैं कि यहां क्या हो रहा है (यह मुझे पता लगाने में थोड़ा सा लगा), वह -lलाइनों के बजाय फ़ाइल नामों को वापस करने के विकल्प का उपयोग कर रहे हैं। फिर वह उस सूची को FILEदूसरे grep में तर्क के रूप में पारित करने के लिए डॉलर चिह्न या पीछे के उद्धरण का उपयोग कर रहा है । यह दूसरे grep को प्रत्येक फ़ाइल की संपूर्णता की खोज करने की अनुमति देता है जो मेरे समाधान के अनुसार व्यक्तिगत लाइनों के बजाय मिली है।
एम्बेडेड

आपने -lदोनों आदेशों को समान मानने के लिए एक विकल्प याद किया ।
पौंग

2

एक पाइप grepको दूसरे में डालें:

grep "string1" /path/to/files/* | grep "string2"


5
यदि फ़ाइल में दो तार अलग-अलग लाइनों पर हैं, तो यह काम नहीं करेगा।
RedGrittyBrick

1
मुझे नहीं पता था के लिए उन में एक ही पंक्ति @RedGrittyBrick होने के लिए एक आवश्यकता नहीं थी
slhck

@ एसएलएचएचके: मैंने अपने उत्तर को यह दिखाने के लिए अपडेट किया है कि मुझे क्या लगता है कि एलडब्ल्यूबीटीसी चाहता है और यह उत्तर ऐसा क्यों नहीं करता है। बेशक, मुझे गलतफहमी हो सकती है कि alwbtc क्या चाहता है और एम्बेडेड है। हेयर स्टाइल को यह सही मिल सकता है - मुझे संदेह नहीं है, हालांकि।
RedGrittyBrick

1

यहाँ बराबर है RedGrittyBrick के उत्तर की कमान :

ack string2 $(ack string1 -l)

उसी तरीके से काम करता है ( ackडिफ़ॉल्ट रूप से वर्तमान निर्देशिका को पुन: खोजता है)। $()खोज के भीतर की सामग्री string1लेकिन -lकेवल उन फ़ाइलनामों को आउटपुट करती है जहां वह स्ट्रिंग पाई गई थी। फिर उन्हें बाहरी कमांड में तर्क के रूप में पारित किया जाता है, जिसका अर्थ string2केवल फाइलों की सूची के भीतर खोजा जाता है।


0
comm -12 <(grep --fixed-strings --files-with-matches "STRING1" /path/to/files/* 2>/dev/null | sort) <(grep --fixed-strings --files-with-matches "STRING1" /path/to/files/* 2>/dev/null | sort)

या कम अतिरेक से:

search_files () { str="$1"; shift; grep -Fl "$str" "$@" 2>/dev/null | sort; }
comm -12 <(search_files "STRING1" /path/to/files/*) <(sf "STRING2" /path/to/files/*)

यह तब काम करेगा जब तार एक ही फाइल की अलग-अलग लाइनों पर हों और अगर फ़ाइल नाम में से कोई एक तार हो तो भी झूठी सकारात्मकता से बचेंगे।


0

@ RedGrittyBrick के समाधान के बारे में विस्तार से बताने के लिए, जो कि कमांड में अनअटेंडेड प्लस को चलाने के दौरान त्रुटि को कम करने के लिए अप्रतिष्ठित चल रहा है और इच्छित फ़ाइलों को खोजने के लिए आपको पुन: विचार करना चाहिए।

grep -l 'STRING1' $(! grep -lrs 'STRING2' /absolute/path/to/search/dir && echo /dev/null)

-sविकल्प त्रुटि संदेशों को दबा देगा
-rविकल्प मनमाने ढंग से नेस्टेड निर्देशिकाओं में स्ट्रिंग की खोज करने की अनुमति देता है जो कि गारंटी
!के साथ संयुक्त है && echo /dev/nullकि कमांड लटका नहीं होगा। अन्यथा, अगर inner grepकोई फ़ाइल नहीं मिलती है तो वह कुछ भी आउटपुट नहीं करेगी जिससे कि outer grepअनिश्चित काल तक खोज पर इनपुट का इंतजार रहेगा। यह समाधान आउटपुट /dev/nullइन मामलों में तो outer grepके लिए खोज करेंगे STRING1में /dev/nullजहां यह कुछ भी नहीं मिल चाहिए था।


0

मैं 2 या अधिक स्ट्रिंग्स करने के लिए एक एक्स्टेंसिबल तरीके की तलाश में था और इसके साथ आया:

grep -rl string1 path-to-files | xargs grep -l string2 | xargs grep -l string3

पहला grep पुनरावर्ती रूप से फ़ाइलों के नाम को खोजता string1है path-to-files

परिणामों को पाइप किया जाता है xargsजिसमें उन फ़ाइलों पर एक या अधिक grep कमांड चलता है string2

इसके बाद परिणाम को दूसरी xargsकमांड में डाला जाता है string3- यह पहली xargsकॉल के समान है , लेकिन एक अलग स्ट्रिंग की तलाश में है।

xargsवसीयत के उपयोग से उन समस्याओं से बचा जा सकता है जहां बहुत सारे परिणाम हैं जो बैक-टिक्स के उपयोग से परिणामी कमांड लाइन बहुत लंबी है।

चेतावनी हम अनुप्रेषित कर सकते हैं से बचने के लिए stderrकरने के लिए /dev/null:

grep -rl string1 path-to-files  2>/dev/null | xargs grep -l string2

बाद के grep कॉल पर इसकी आवश्यकता नहीं है क्योंकि string1फ़ाइल के अंदर पहले से ही पाया गया है इसलिए अनुमतियाँ अच्छी हैं।

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