কীভাবে গ্রেপ-ভি করবেন এবং ম্যাচের পরের লাইনটি বাদ দেবেন?


15

গ্রেপ রেজেক্সের সাথে মিলে প্রতিটি লাইনের জন্য কীভাবে 2 টি লাইন ফিল্টার করা যায়?
এটি আমার ন্যূনতম পরীক্ষা:

SomeTestAAAA
EndTest
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestAABC
EndTest
SomeTestACDF
EndTest

এবং স্পষ্টতই আমি চেষ্টা করেছি উদাহরণস্বরূপ grep -vA 1 SomeTestAAযা কাজ করে না।

কাঙ্ক্ষিত আউটপুট:

SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest

grep -v 'SomeTextAA' | ইউনিক?
ডার্কহার্ট

উত্তর:


14

আপনি (পিসিআরই) এর grepসাথে ব্যবহার করতে পারেন -P:

grep -P -A 1 'SomeTest(?!AA)' file.txt

(?!AA)শূন্য প্রস্থের নেতিবাচক বর্ণনাহীন প্যাটার্নটি নিশ্চিত করে যে এর AAপরে আর নেই SomeTest

পরীক্ষা:

$ grep -P -A 1 'SomeTest(?!AA)' file.txt 
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest

বিন্দুগুলির জন্য পালানোর চরিত্রটি কী? Some.Test.AA এর মত?
বেহরোজ

1
@ বেহরোজ \.তাই grep -P -A 1 'SomeTest\.(?!AA)' file.txtবা এর মাধ্যমে বিন্দুগুলি রক্ষা করুনgrep -P -A 1 'SomeTest(?!\.AA)' file.txt
হিমাইল

এটি এই বিশেষ ক্ষেত্রে কাজ করে কারণ ওপিতে নমুনা লাইনগুলি জোড়া আসে SomeTest*\nEndTestতাই আপনি grepমিলিয়ে সমস্ত লাইনের সাথে মিলে যায় SomeTest*তবে SomeTestAAম্যাচের পরে প্রসঙ্গের এক লাইন নয় । ইনপুটটিতে আরও কয়েকটি লাইন যুক্ত করুন (উদাহরণস্বরূপ foobarপ্রতিটি EndTestলাইনের পরে একটি লাইন যুক্ত করুন ) তারপরে আবার চেষ্টা করুন।
don_crissti

1
@ ডন_ক্রিসটি সত্য যে আমি এরই মধ্যে কাজ করেছি।
বেহরোজ

@ বেহরোজ - আপনি কীভাবে এই চারপাশে কাজ করেছেন তা আমাদের সাথে ভাগ করে নেওয়ার এবং আপনার প্রশ্নের অধীনে আমার মন্তব্যের জবাব দেওয়ার বিষয়ে যত্নশীল?
don_crissti

4

এখানে sedসলিউশন ( -nযেমন কোনও স্বয়ং-মুদ্রণ সহ নয়) যা স্বেচ্ছাসেবী ইনপুট নিয়ে কাজ করে:

sed -n '/SomeTestAA/!p          # if line doesn't match, print it
: m                             # label m
//{                             # if line matches
$!{                             # and if it's not the last line
n                               # empty pattern space and read in the next line
b m                             # branch to label m (so n is repeated until a
}                               # line that's read in no longer matches) but
}                               # nothing is printed
' infile

যেমন একটি ইনপুট সঙ্গে

SomeTestAAXX
SomeTestAAYY
+ one line
SomeTestONE
Message body
EndTest
########
SomeTestTWO
something here
EndTest
SomeTestAABC
+ another line
SomeTestTHREE
EndTest
SomeTestAA
+ yet another line

চলমান

sed -n -e '/SomeTestAA/!p;: m' -e '//{' -e '$!{' -e 'n;b m' -e '}' -e'}' infile

আউটপুট

SomeTestONE
Message body
EndTest
########
SomeTestTWO
something here
EndTest
SomeTestTHREE
EndTest

এটি হ'ল এটি যে লাইনগুলি grep -A1 SomeTestAA infileনির্বাচন করবে তা সরিয়ে দেয় :

SomeTestAAXX
SomeTestAAYY
+ one line
--
SomeTestAABC
+ another line
--
SomeTestAA
+ yet another line

মজাদার. আমি যে //মেলে বুঝতে পারিনি /SomeTestAA/। আমি ভাবলাম, এই ক্ষেত্রে, এটা অস্বীকার অভিব্যক্তি মিল খেতে হবে: /SomeTestAA/!। (+1)
পিটার.ও

@ পিটার.ও - ধন্যবাদ! না, চশমা অনুযায়ী, একটি খালি আরআর সর্বদা শেষ কমান্ডে ব্যবহৃত সর্বশেষ আরই এর সাথে মেলে ; !অংশ নয় পুনরায়- , এটি একটি এর sedজিনিস।
don_crissti

3

মাল্টি-লাইন অঞ্চলগুলিকে একক রেকর্ড হিসাবে দেখায় এমন কোনও কিছুর সাথে আপনার ভাগ্য ভাল হতে পারে। এমন একটি আছে sgrepযা আমি বেশি ব্যবহার করি নি।

এছাড়াও জঞ্জাল রয়েছে, যেখানে আপনি নিজের পছন্দ অনুযায়ী ইনপুট রেকর্ড বিভাজক এবং আউটপুট রেকর্ড বিভাজক সেট করতে পারেন।

pat="^SomeTestAA"
awk  'BEGIN{ RS=ORS="\nEndTest\n"} !/'"$pat/" foo

বেশিরভাগ awk প্রোগ্রামটি একক-উদ্ধৃত, তবে আমি শেষে ডাবল কোটে পরিবর্তন করি যাতে $patশেল ভেরিয়েবলটি প্রসারিত করা যায়।


awk -vpat="^SomeTestAA" -vRS="\nEndTest\n" 'BEGIN{ ORS=RS } $0 !~ pat' file
পিটার.ও

3

একটি বিকল্প হ'ল pএরল cঅসম্পোটিভ rউদাহরণস্বরূপ eএক্সপ্রেশন grep:

pcregrep -Mv 'SomeTestAA.*\n' file

বিকল্পটি -Mপ্যাটার্নটিকে আরও এক লাইনের সাথে মেলাতে দেয়।


1
@ don_crissti উভয় লাইন সরানো হবে। ওপির স্পেসিফিকেশন এই কেসটি কভার করে না।
জিম্মিজ

এটি ওপিএসের নমুনাটি এবং স্পষ্টভাবে এই জাতীয় মামলার প্রচ্ছদকে স্পষ্ট করে না, এটি কীভাবে কাজ করে তা জানতে আগ্রহী (আমি পিসিরির সাথে পরিচিত নই) কারণ একটানা সংখ্যক লাইন মিলছে এই কাজ করে (এটি সরিয়ে দেয়) প্রসঙ্গ লাইনটিও) এবং একত্রে সংখ্যক পরপর রেখার সাথে মেলে যা ব্যর্থ হয় (এটি প্রসঙ্গের লাইনটি পরে সরিয়ে দেয় না)।
don_crissti

(জিএনইউ) grepইতিমধ্যে পিসিআরই সমর্থন করে ( -Pবিকল্পের মাধ্যমে ), ব্যবহারের সুবিধা কী pcregrep?
আরিফেল

@arielf বিকল্প grepসমর্থন করে না -M
জিম্মিজ

1

আপনি একটি লাইন মুছে ফেলতে GNU- seddকমান্ডটি ব্যবহার করতে পারেন , এবং /pat/,+Nপ্যাটার্ন এবং পরবর্তী এন লাইনের সাথে মিলে যাওয়া লাইনগুলি নির্বাচন করতে এটির সাথে পূর্ববর্তী করুন । আপনার ক্ষেত্রে, এন = 1 যেহেতু আপনি কেবল মিলের লাইনের পরে একক পরবর্তী লাইনটি মুছতে চান:

sed -e '/SomeTestAAAA/,+1d'

1

মান ব্যবহার sed:

$ sed '/SomeTestAA/{ N; d; }' file
SomeTestABCD
EndTest
SomeTestDEFG
EndTest
SomeTestACDF
EndTest

sedস্ক্রিপ্ট লাইন দ্বারা ইনপুট ফাইল লাইন parses, এবং যখন একটি লাইন ধরণের সাথে মেলা SomeTestAA, দুই sedসম্পাদনা কমান্ড Nএবং dমৃত্যুদন্ড কার্যকর করা হয়। Nকমান্ড প্যাটার্ন স্থান (বাফার যে ইনপুটের পরের লাইনে appends sedকরতে পারেন সম্পাদন করা), এবং dপ্যাটার্ন স্থান মুছে ফেলে এবং পরবর্তী চক্র শুরু হয়।


1

নীচে সেড কমান্ড দিয়ে চেষ্টা করা হয়েছে এবং এটি দুর্দান্ত কাজ করেছে

হুকুম

sed  '/SomeTestAA/,+1d' filename

আউটপুট

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