কিছু মনে করবেন না, শুধু ব্যবহার pcregrep
যেমন প্রস্তাব @StephaneChazelas দ্বারা।
এই কাজ করা উচিত:
$ find . -name "*.cpp" |
while IFS= read -r file; do
grep -A 3 Foo "$file" | grep -q Bar || echo "$file";
done
-A
মিলটিভ রেখা এবং এন নিম্নলিখিত লাইনগুলিকে আউটপুট দেওয়ার জন্য গ্রেপের সুইচ ব্যবহার করা উচিত । আপনি তারপরে ফলাফলটি পাস করে 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