मैंने इसका बहुत उपयोग किया, मैं जो सुधार करने की कोशिश करता हूं वह गूंज फ़ाइल नामों से बचने के लिए है जो कि जीआरईपी में मेल नहीं खाता। ऐसा करने का बेहतर तरीका?
for file in `find . -name "*.py"`; do echo $file; grep something $file; done
मैंने इसका बहुत उपयोग किया, मैं जो सुधार करने की कोशिश करता हूं वह गूंज फ़ाइल नामों से बचने के लिए है जो कि जीआरईपी में मेल नहीं खाता। ऐसा करने का बेहतर तरीका?
for file in `find . -name "*.py"`; do echo $file; grep something $file; done
जवाबों:
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 और डेरिवेटिव पर भी काम करता है)।
आप जीएनयू ग्रेप का उपयोग कर रहे हैं, तो आप अपने उपयोग कर सकते हैं -r
या --recursive
आप के लिए यह सरल खोज करने के लिए विकल्प:
grep -r --include '*.py' -le "$regexp" ./ # for filenames only
grep -r --include '*.py' -He "$regexp" ./ # for filenames on each match
आपको केवल तभी ज़रूरत है find
जब आपको अधिक उन्नत विधेय की आवश्यकता हो।
grep
, grep
निर्देशिकाओं के लिए सहानुभूति या पीछे वाले सहानुभूति के अंदर दिख सकता है या नहीं। आप अन्य प्रकार की गैर-नियमित फ़ाइलों की हैंडलिंग में कुछ भिन्नताएं भी पा सकते हैं।
आप 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
आप कुछ इस तरह की कोशिश कर सकते हैं:
find . -name "*.py:" -exec grep -l {} \;
यह हर फाइल के लिए grep कमांड निष्पादित करता है, जिसे खोज कमांड और उसके मानक फाइंड कमांड फीचर द्वारा खोजा गया है
ऐसे grep
विकल्प हैं जो डिफ़ॉल्ट रूप से आपके इच्छित प्रारूप में उनके परिणाम देते हैं। 2 सबसे लोकप्रिय जो मुझे पता है कि ag
(उर्फ "सिल्वर खोजकर्ता") और हैं ack
। ag
के लिए एक तेजी से विकल्प के रूप में विज्ञापित है 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) {
...
मैं आपको यहां नहीं दिखा सकता, लेकिन आउटपुट बड़े करीने से रंगा हुआ है। मुझे एक जैतून का हरे रंग में फिलामेंट मिलता है, सोने के पीले रंग में लाइन नंबर, और रक्त लाल में प्रत्येक पंक्ति में मिलान किया हुआ टुकड़ा। हालांकि रंग अनुकूलन योग्य हैं।