"ফু" এর উদাহরণগুলি খুঁজে পেতে গ্রেপ করুন যেখানে "বার" 10 লাইনের মধ্যে উপস্থিত হবে না


10

মনে করুন যে আমি সমস্ত সিপিপি ফাইল যেখানে "ফু" ঘটে তার জন্য একটি সম্পূর্ণ গাছ অনুসন্ধান করতে চাই। আমি করতে পারি:

find . -name "*.cpp" | xargs grep "Foo"

এখন ধরা যাক আমি কেবলমাত্র সেই উদাহরণগুলিকেই তালিকাবদ্ধ করতে চাই যেখানে অন্য কিছু স্ট্রিং বলুন, "বার" পূর্ববর্তী ফলাফলের 3 লাইনের মধ্যে ঘটে না

সুতরাং দুটি ফাইল দেওয়া:

a.cpp

1 Foo
2 qwerty
3 qwerty

b.cpp

1 Foo
2 Bar
3 qwerty

আমি একটি সাধারণ অনুসন্ধান তৈরি করতে চাই যেখানে a.cpp থেকে "ফু" পাওয়া যায়, তবে বিসিপিপি থেকে "ফু" পাওয়া যায় না।

মোটামুটি সহজ উপায়ে এটি সম্পাদনের কোনও উপায় আছে কি?


সমাধান সমাধান গ্রেপ -A এবং / অথবা গ্রেপ-বি এবং / অথবা গ্রেপ-সি বিকল্প হতে পারে। আমি চেষ্টা করছি কিন্তু কোনও
সাশ্রয় ছাড়াই

@ মুরেলিও 79৯: আমার বর্তমান তত্ত্বটি এটি। প্রসঙ্গের জন্য -A 10 ব্যবহার করে "ফু" জন্য গ্রেপ করুন। পাইপ যে গ্রেপ -v বার। ফাইলের নাম এবং লাইন নম্বর পেতে সেটিকে পাইপ করুন। সেই লাইনটি মুদ্রণের জন্য এটি (কিছু?) পাইপ করুন।
জন ডিবলিং

উত্তর:


17

সহ pcregrep:

pcregrep --include='\.cpp$' -rnM 'Foo(?!(?:.*\n){0,2}.*Bar)' .

কীটি -Mবিকল্পটিতে রয়েছে যা একচেটিয়া pcregrepএবং একাধিক লাইনের সাথে মেলে ব্যবহার করা হয় ( pcregrepআরআর এটির দাবিতে হাঁটার সময় প্রয়োজনীয় হিসাবে ইনপুট ফাইল থেকে আরও ডেটা টান দেয়)।

(?!...)পার্ল / পিসিআরই নেগেটিভ লুক-ফরোয়ার্ড আরই অপারেটর। Foo(?!...)ম্যাচ Fooযতদিন ...কি অনুসরণ সাথে মিলছে না।

...হচ্ছে (?:.*\n){0,2}.*Bar( .একটি নতুন লাইন চরিত্রের সাথে মেলে না), এটি 0 থেকে 2 লাইন এবং তার পরে একটি লাইন থাকে Bar


+1: দুর্দান্ত। অনেক ধন্যবাদ; আমি নিশ্চিত যে সঠিক রেগেক্সটি বের করা সহজ ছিল না। আমি আপনার প্রচেষ্টার প্রশংসা করি এটি যেমনটি চেয়েছিল ঠিক তেমন কাজ করছে বলে মনে হচ্ছে।
জন ডিবলিং

2
পার্শ্ব প্রশ্ন যদি আপনি উত্তর দিতে যত্নশীল। আপনি কীভাবে জানতে পারলেন pcregrep? আমি এর আগে কখনও শুনিনি।
জন ডিবলিং

@ জনডিবলিং, আমি ব্যক্তিগতভাবে সম্প্রতি ইউনিক্স.এসইতে খুঁজে পেয়েছি । এই আরআর বিশেষত জটিল নয়, বিশেষত যখন আপনি (?!...)নেতিবাচক চেহারা-এগিয়ে perlআরই অপারেটরের সাথে পরিচিত হন ।
স্টাফেন চেজেলাস

9

কিছু মনে করবেন না, শুধু ব্যবহার 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কারণ এর সাথে লাইনটি Bar3 টির বেশি লাইনের পরে থাকে 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

+1 ঝরঝরে-ও। আমি যতটা আশা করেছিলাম তার চেয়ে আরও জটিল, তবে মোটেও খারাপ নয়।
জন ডিবলিং

এটি ধরে নিয়েছে "ফু" কেবল একবার ঘটে। এটি যে ফাইলগুলিকে ধারণ করে না সেগুলিও প্রতিবেদন করবে Foo। আপনার উদ্ধৃতি নেই।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস ধন্যবাদ, উদ্ধৃতি স্থির করা হয়েছে। আপনি নথির সাথে ফাইল প্রতিবেদন করা সম্পর্কে বেশ সঠিক Fooএবং আমি এটি ঠিক করেছি তবে এর একাধিক উদাহরণ সম্পর্কে আমি আপনার বক্তব্যটি দেখতে পাচ্ছি না Foo। এটি তাদের সঠিকভাবে মোকাবেলা করা উচিত।
টেরডন

@ জনডিবলিং আপডেট দেখুন।
টেরডন

1
এটি "ফু" এর 100 টি লাইনযুক্ত "বার" এর পরে থাকা কোনও ফাইলের প্রতিবেদন করবে না।
স্টাফেন চেজেলাস

0

অনির্ধারিত, আমি আমার ফোনে আছি:

find . -name "*.cpp" | xargs awk '/foo/{t=$0;c=10}/bar/{c=0;t=""}c{c--}t&&!c{print t;t=""}END&&t{print t}' 

এরকম কিছু.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.