कोई बात नहीं, बस का उपयोग pcregrep
के रूप में सुझाव दिया @StephaneChazelas द्वारा।
यह काम करना चाहिए:
$ find . -name "*.cpp" |
while IFS= read -r file; do
grep -A 3 Foo "$file" | grep -q Bar || echo "$file";
done
-A
मिलान लाइनों और एन निम्नलिखित लाइनों के उत्पादन के लिए grep के स्विच का उपयोग करने का विचार है । आप तब परिणाम को पास करते हैं grep Bar
और यदि वह मेल नहीं खाता (बाहर निकलें> 0), तो आप फ़ाइल का नाम गूँजते हैं।
यदि आप जानते हैं कि आपके पास फ़ाइल नाम हैं (कोई रिक्त स्थान, नई लाइनें या अन्य अजीब अक्षर नहीं), तो आप इसे सरल कर सकते हैं:
$ for file in $(find . -name "*.cpp"); do
grep -A 3 Foo "$file" | grep -q Bar || echo "$file";
done
उदाहरण के लिए:
terdon@oregano foo $ cat a.cpp
1 Foo
2 qwerty
3 qwerty
terdon@oregano foo $ cat b.cpp
1 Foo
2 Bar
3 qwerty
terdon@oregano foo $ cat c.cpp
1 Foo
2 qwerty
3 qwerty
4 qwerty
5. Bar
terdon@oregano foo $ for file in $(find . -name "*.cpp"); do grep -A 3 Foo "$file" | grep -q Bar || echo "$file"; done
./c.cpp
./a.cpp
ध्यान दें कि c.cpp
युक्त होने के बावजूद वापस आ गया है Bar
क्योंकि रेखा Bar
3 रेखाओं से अधिक है Foo
। आप उस मान की संख्या को नियंत्रित करते हैं जिसे आप खोज करना चाहते हैं -A
:
$ for file in $(find . -name "*.cpp"); do
grep -A 10 Foo "$file" | grep -q Bar || echo "$file";
done
./a.cpp
यहाँ एक छोटा है (आप का उपयोग करते हुए bash
):
$ shopt -s globstar
$ for file in **/*cpp; do
grep -A 10 Foo "$file" | grep -q Bar || echo "$file";
done
जरूरी
जैसा कि स्टीफन चेज़ेलस ने टिप्पणियों में बताया है, उपरोक्त समाधान उन फ़ाइलों को भी प्रिंट करेंगे जिनमें बिल्कुल नहीं हैं Foo
। इससे बचा जाता है:
for file in **/*cpp; do
grep -qm 1 Foo "$file" &&
(grep -A 3 Foo "$file" | grep -q Bar || echo "$file");
done