फाइल और गूंज नाम केवल पैटर्न के साथ मिला


16

मैंने इसका बहुत उपयोग किया, मैं जो सुधार करने की कोशिश करता हूं वह गूंज फ़ाइल नामों से बचने के लिए है जो कि जीआरईपी में मेल नहीं खाता। ऐसा करने का बेहतर तरीका?

    for file in `find . -name "*.py"`; do echo $file; grep something $file; done

जवाबों:


24
find . -name '*.py' -exec grep something {} \; -print

मिलान लाइनों के बाद फ़ाइल का नाम प्रिंट करेगा ।

find . -name '*.py' -exec grep something /dev/null {} +

प्रत्येक मिलान पंक्ति के सामने फ़ाइल का नाम प्रिंट करेगा (हम /dev/nullउस मामले के लिए जोड़ते हैं जहां केवल एक मिलान फ़ाइल है क्योंकि grepफ़ाइल नाम प्रिंट नहीं करता है यदि यह देखने के लिए केवल एक फ़ाइल पास की गई है। GNU कार्यान्वयन के लिए grepएक -Hविकल्प है। विकल्प के रूप में)।

find . -name '*.py' -exec grep -l something {} +

उन फ़ाइलों के केवल फ़ाइल नाम प्रिंट करेगा जिनमें कम से कम एक मिलान रेखा है।

मिलान लाइनों से पहले फ़ाइल का नाम प्रिंट करने के लिए , आप इसके बजाय awk का उपयोग कर सकते हैं:

find . -name '*.py' -exec awk '
  FNR == 1 {filename_printed = 0}
  /something/ {
    if (!filename_printed) {
      print FILENAME
      filename_printed = 1
    }
    print
  }' {} +

या grepप्रत्येक फ़ाइल के लिए दो बार कॉल करें - हालांकि यह कम कुशल होगा क्योंकि यह grepप्रत्येक फ़ाइल के लिए कम से कम एक कमांड और दो तक चलेगा (और फ़ाइल की सामग्री को दो बार पढ़ें):

find . -name '*.py' -exec grep -l something {} \; \
                    -exec grep something {} \;

किसी भी मामले में, आप findउस तरह के आउटपुट पर लूप नहीं करना चाहते हैं और अपने चर को कोट करना याद रखें

यदि आप GNU टूल के साथ शेल लूप का उपयोग करना चाहते हैं:

find . -name '*.py' -exec grep -l --null something {} + |
   xargs -r0 sh -c '
     for file do
       printf "%s\n" "$file"
       grep something < "$file"
     done' sh

(FreeBSD और डेरिवेटिव पर भी काम करता है)।


6

आप जीएनयू ग्रेप का उपयोग कर रहे हैं, तो आप अपने उपयोग कर सकते हैं -rया --recursiveआप के लिए यह सरल खोज करने के लिए विकल्प:

grep -r --include '*.py' -le "$regexp" ./ # for filenames only
grep -r --include '*.py' -He "$regexp" ./ # for filenames on each match

आपको केवल तभी ज़रूरत है findजब आपको अधिक उन्नत विधेय की आवश्यकता हो।


1
जीएनयू के संस्करण के आधार पर grep, grepनिर्देशिकाओं के लिए सहानुभूति या पीछे वाले सहानुभूति के अंदर दिख सकता है या नहीं। आप अन्य प्रकार की गैर-नियमित फ़ाइलों की हैंडलिंग में कुछ भिन्नताएं भी पा सकते हैं।
स्टीफन चेज़लस

5

आप grep को आउटपुट में फ़ाइल नाम शामिल करने के लिए कह सकते हैं। इसलिए यदि कोई मैच है तो इसे कंसोल पर दिखाया जाएगा; यदि किसी फ़ाइल के भीतर कोई मेल नहीं है, तो उस फ़ाइल के लिए कोई लाइन नहीं छपी होगी।

find . -name "*.py" | xargs grep -n -H something

से man grep:

-H       Always print filename headers with output lines
-n, --line-number
         Each output line is preceded by its relative line number in the file, starting at line 1.  The line number counter is reset for each file processed.
         This option is ignored if -c, -L, -l, or -q is specified.

यदि आपकी फ़ाइलों में रिक्त स्थान के साथ नाम हो सकते हैं, तो आपको एक सेपरेटर के रूप में NUL वर्ण का उपयोग करने के लिए पाइप को स्विच करना होगा। पूरा कमांड अब इस तरह दिखेगा:

find . -name "*.py" -print0 | xargs -0 grep -n -H something

1

आप कुछ इस तरह की कोशिश कर सकते हैं:

find . -name "*.py:" -exec grep -l {} \;

यह हर फाइल के लिए grep कमांड निष्पादित करता है, जिसे खोज कमांड और उसके मानक फाइंड कमांड फीचर द्वारा खोजा गया है


1

-lतर्क का उपयोग करें ।

for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done

अधिक खोज का उपयोग होगा:

for file in $(find . -name '*.py' -exec grep -l something '{}' +); do echo "$file"; grep something $file; done

1

ऐसे grepविकल्प हैं जो डिफ़ॉल्ट रूप से आपके इच्छित प्रारूप में उनके परिणाम देते हैं। 2 सबसे लोकप्रिय जो मुझे पता है कि ag(उर्फ "सिल्वर खोजकर्ता") और हैं ackagके लिए एक तेजी से विकल्प के रूप में विज्ञापित है ack

$ ag '^\w+\s*\w+\(' ~/build/i3/src
build/i3/src/display_version.c
58:void display_running_version(void) {

build/i3/src/load_layout.c
42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings =
518:json_content_t json_determine_content(const char *filename) {
575:void tree_append_json(Con *con, const char *filename, char **errormsg) {

build/i3/src/x.c
64:CIRCLEQ_HEAD(state_head, con_state) state_head =
67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head =
70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head =
97:void x_con_init(Con *con, uint16_t depth) {
...

मैं आपको यहां नहीं दिखा सकता, लेकिन आउटपुट बड़े करीने से रंगा हुआ है। मुझे एक जैतून का हरे रंग में फिलामेंट मिलता है, सोने के पीले रंग में लाइन नंबर, और रक्त लाल में प्रत्येक पंक्ति में मिलान किया हुआ टुकड़ा। हालांकि रंग अनुकूलन योग्य हैं।

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