গ্রেপ-তে কোনও লোভী ম্যাচ কীভাবে করবেন?


177

আমি সংক্ষিপ্ততম ম্যাচটি গ্রেপ করতে চাই এবং প্যাটার্নটি এমন হওয়া উচিত:

<car ... model=BMW ...>
...
...
...
</car>

... মানে যে কোনও অক্ষর এবং ইনপুটটি একাধিক লাইন।


উত্তর:


276

আপনি একটি লোভী (বা অলস) মিল খুঁজছেন। নিয়মিত প্রকাশে অ-লোভী মিল পেতে ?আপনার কোয়ান্টিফায়ার পরে মডিফায়ার ব্যবহার করতে হবে use উদাহরণস্বরূপ, আপনি পরিবর্তন করতে পারেন .*থেকে.*?

ডিফল্টরূপে grepঅ-লোভী সংশোধকগুলিকে সমর্থন করে না, তবে আপনি grep -Pপার্ল বাক্য গঠন ব্যবহার করতে পারেন।


3
eegg: ডট সমস্ত সংশোধক এছাড়াও মাল্টলাইন হিসাবে পরিচিত। এটি একটি পরিবর্তনকারী যা "" পরিবর্তন করে। নিউলাইনগুলি অন্তর্ভুক্ত করতে আচরণের সাথে মেলে (সাধারণত এটি হয় না)। সেখানে, grep এ ধরনের কোন পরিবর্তক, কিন্তু সেখানে রয়েছে pcregrep
উ। উইলসন

1
সংশোধন: এটি সমর্থন করে এমন বেশিরভাগ রেইগেক্স স্বাদে, যে মোডটি নিউলাইনগুলিকে. মেলাতে দেয় তাকে ডটল বা একক-লাইন মোড বলা হয়; রুবি হ'ল একমাত্র যাকে এটিকে মাল্টলাইন বলে । অন্যান্য স্বাদে, মাল্টলাইন হ'ল মোড যা নোঙ্গরগুলিকে ( ^এবং $) লাইন সীমানায় মিলিয়ে দেয়। রুবির কোনও সমতুল্য মোড নেই কারণ রুবিতে তারা সর্বদা সেভাবেই কাজ করে।
অ্যালান মুর

5
-Pআমার উপর সম্পূর্ণ নতুন ছিল, আমি আনন্দের সাথে বছরের পর বছর ধরে দূরে চলেছি, এবং কেবল ব্যবহার করছি -E... এতগুলি নষ্ট বছর! - স্বরে নোট করুন: ম্যান পৃষ্ঠাগুলিকে একটি (আরও বেশি!) নিয়মিত জিনিস হিসাবে পুনরায় পড়ুন, আপনি কখনও পর্যাপ্ত সুইচ এবং বিকল্পগুলি হজম করেন না।
অক্টোডো

29
কিছু প্ল্যাটফর্মে (যেমন ম্যাক ওএস এক্স) grepসমর্থন করে না -P, তবে আপনি যদি ব্যবহার করেন তবে আপনি একই ফলাফল অর্জন করতে প্যাটার্নটি ব্যবহার egrepকরতে পারেন .*?egrep -o 'start.*?end' text.html
সল্টনিট

4
@ স্যালটিএনটস মন্তব্যটির সম্প্রসারণ হিসাবে, ম্যাক ওএস এক্স সমর্থন করে না -Pতবে পরামর্শ দেওয়া কাজগুলি ঠিকঠাক করে -Eকল করবে । egrep.*?
ফ্রেডরিক এরল্যান্ডসন

83

আসল .*?একমাত্র কাজ করে perl। সমমানের গ্রেপ এক্সটেন্ডেড রেজিএক্সএক্স সিন্ট্যাক্সটি কী হবে তা আমি নিশ্চিত নই। ভাগ্যক্রমে আপনি গ্রেপ দিয়ে পার্ল সিনট্যাক্স ব্যবহার করতে পারেন তাই grep -Pকাজ করবে তবে grep -Eযা egrepকাজ করবে না তার মতো (এটি লোভী হবে)।

আরও দেখুন: http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html


9
grep -Pজিএনইউ গ্রেপ ২.৯-তে কাজ করে না - এটি চেষ্টা করে (এটি ত্রুটি করে না, নিঃশব্দে এটি প্রয়োগ করে না ?Inter ইন্টারটেস্টলি উভয়ই শ্রেণি যেমন না :env|grep '[^\=]*\='
রবার্তো টমিস

2
ডারউইন / ওএস এক্স 10.8 মাউন্টেন লায়নটিতে কোনও grep -Pবিকল্প বা pgrepআদেশ নেই , তবে egrepদুর্দান্ত কাজ করে।
স্টিভ এইচএইচএইচ

2
pgrepআমার ওএস এক্স ১০.৯ বাক্সে একটি কমান্ড রয়েছে, তবে এটি সম্পূর্ণ ভিন্ন প্রোগ্রাম যার উদ্দেশ্য "নাম অনুসারে প্রক্রিয়াগুলি সন্ধান করা বা সংকেত করা" is
Desty

@ রবার্টটোমের এখানে 6 বছরের পুরানো মন্তব্যের প্রতিক্রিয়া, কিন্তু .... আমি এটিও ভেবেছিলাম এবং তখন বুঝতে পেরেছিলাম যে আমি একাধিক অ-লোভী ম্যাচ পাচ্ছি। উদাহরণস্বরূপ, রঙিন টার্মিনালে আপনি দেখতে পাচ্ছেন যে cho প্রতিধ্বনি "বিবিবিবিবি" | grep -P 'b। *? b'` 2 টি ম্যাচ ফেরায়।
zzxyz

12

আমার গ্রেপ যা এই থ্রেডে স্টাফ চেষ্টা করার পরে কাজ করে:

echo "hi how are you " | grep -shoP ".*? "

কেবলমাত্র আপনার প্রতিটি লাইনে একটি স্থান যুক্ত করার বিষয়টি নিশ্চিত করুন

(শব্দগুলি ছিটিয়ে দেওয়ার জন্য আমার এক লাইনের সন্ধান ছিল)


3
-shoPসুন্দর স্মৃতিচারণা :)
মারিউজ

echo "bbbbb" | grep -shoP 'b.*?b'কিছুটা শেখার অভিজ্ঞতা bit সুস্পষ্টভাবে অলসতার ক্ষেত্রে কেবলমাত্র আমার পক্ষে কাজ করেছে।
zzxyz

12

grep

অ-লোভী মিলের জন্য grepআপনি অবহেলিত চরিত্রের শ্রেণিটি ব্যবহার করতে পারেন। অন্য কথায়, ওয়াইল্ডকার্ডগুলি এড়ানোর চেষ্টা করুন।

উদাহরণস্বরূপ, পৃষ্ঠা লিখিত সামগ্রী থেকে জেপিগ ফাইলের সমস্ত লিঙ্ক আনার জন্য, আপনি ব্যবহার করতে পারেন:

grep -o '"[^" ]\+.jpg"'

একাধিক লাইনের সাথে ডিল করতে, xargsপ্রথমে ইনপুটটি পাইপ করুন । কর্মক্ষমতা জন্য, ব্যবহার করুন ripgrep


3

সংক্ষিপ্ত উত্তরটি পরবর্তী নিয়মিত প্রকাশটি ব্যবহার করছে:

(?s)<car .*? model=BMW .*?>.*?</car>
  • (? গুলি) - এটি মাল্টলাইন জুড়ে একটি মিল তৈরি করে
  • । *? - কোনও চরিত্রের সাথে মেলে, অলস উপায়ে বেশ কয়েকবার (ন্যূনতম মিল)

একটি (সামান্য) আরও জটিল উত্তর হ'ল:

(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>

এটি নীচের পাঠ্যে কার 1 এবং কার 2 এর সাথে মিল পাওয়া সম্ভব করবে

<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
  • (..) একটি ক্যাপচারিং গ্রুপকে উপস্থাপন করে
  • এই প্রসঙ্গে 1 ডলার গোষ্ঠী নম্বর 1 টি ক্যাপচারের মাধ্যমে সাম্প্রতিক ম্যাচের মতো একই পাঠ্যটির সাথে মেলে

1

দুঃখিত, আমি 9 বছর দেরি করে ফেলেছি, তবে এটি 2020 সালে দর্শকদের জন্য কাজ করতে পারে।

সুতরাং ধরুন আপনার মত একটি লাইন আছে "Hello my name is Jello"। এখন আপনি যে শব্দগুলি দিয়ে শুরু 'H'এবং শেষ হতে হবে তার মধ্যে যে 'o'কোনও সংখ্যক অক্ষর রেখে শুরু করতে পারেন । এবং আমরা লাইন চাই না আমরা শুধু শব্দ চাই। সুতরাং এর জন্য আমরা এক্সপ্রেশনটি ব্যবহার করতে পারি:

grep "H[^ ]*o" file

এটি সমস্ত শব্দ ফিরে আসবে। এটি যেভাবে কাজ করে তা হ'ল: এটি স্থানের অক্ষরের পরিবর্তে সমস্ত অক্ষরকে অনুমতি দেবে, এইভাবে আমরা একই লাইনে একাধিক শব্দ এড়াতে পারি।

এখন আপনি স্পেস অক্ষরটি অন্য যে কোনও চরিত্রের দ্বারা প্রতিস্থাপন করতে পারেন। ধরুন প্রাথমিক লাইনটি ছিল "Hello-my-name-is-Jello", তবে আপনি শব্দটি ব্যবহার করে শব্দটি পেতে পারেন:

grep "H[^-]*o" file

0

আমি জানি যে এটি একটি মৃত পোস্টের একটি বিট কিন্তু আমি কেবল লক্ষ্য করেছি যে এটি কাজ করে। এটি আমার আউটপুট থেকে ক্লিন আপ এবং ক্লিনআপ উভয়ই সরিয়ে দিয়েছে।

> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.