এডাব্লুকে: লাইন প্যাটার্ন থেকে ক্যাপচার করা গোষ্ঠীকে অ্যাক্সেস করুন


229

আমার কাছে যদি একটি awk কমান্ড থাকে

pattern { ... }

এবং প্যাটার্ন একটি ক্যাপচারিং গ্রুপ ব্যবহার করে, আমি কীভাবে ব্লকে ক্যাপচার করা স্ট্রিংটি অ্যাক্সেস করতে পারি?



কখনও কখনও (সাধারণ ক্ষেত্রে) ফিল্ড বিভাজক সামঞ্জস্য করা সম্ভব ( FS) এবং এটির সাথে কোনটি মেলে তা পছন্দ করে $field। ইনপুট প্রিফর্ম্যাট করাও সহায়তা করতে পারে।
ক্রিজিসটফ জাবোসস্কি

1
একটা হল ভাল উত্তর ডুপ্লিকেট প্রশ্নে।
স্যামুয়েল এডউইন ওয়ার্ড

2
স্যামুয়েল এডউইন ওয়ার্ড: এটিও একটি দুর্দান্ত উত্তর! তবে এটিরও প্রয়োজন gawk(যেহেতু এটি ব্যবহার করে gensub)।
রামপিন

উত্তর:


176

এটি ছিল মেমরি লেনের নিচে ঘুরে ...

আমি দীর্ঘদিন আগে পার্ল দ্বারা জাজকে প্রতিস্থাপন করেছি।

স্পষ্টতই এডব্লিউকে নিয়মিত এক্সপ্রেশন ইঞ্জিন এর গ্রুপগুলি ক্যাপচার করে না।

আপনি যেমন কিছু ব্যবহার বিবেচনা করতে পারেন:

perl -n -e'/test(\d+)/ && print $1'

-n ফ্ল্যাগটি পার্লকে প্রতিটি লাইনের উপরে লম্বা করে দেয় যেমন করণীয়ের মতো করে।


3
স্পষ্টতই কেউ একমত না। এই ওয়েব পৃষ্ঠাটি 2005 সালের: tek-tips.com/faqs.cfm?fid=5674 এটি নিশ্চিত করে যে আপনি মিলিত গোষ্ঠীগুলিকে পুনরায় ব্যবহার করতে পারবেন না।
পিটার টিলেম্যানস

3
আমি প্রায় সকল ব্যবহারের ক্ষেত্রে 'পার্ল-এন -পি-ই ...' পছন্দ করি, কারণ এটি আরও নমনীয়, আরও শক্তিশালী এবং আমার মতে একটি সিনার বাক্য গঠন রয়েছে।
পিটার টিলেম্যানস

15
gawk! = awk। এগুলি বিভিন্ন সরঞ্জাম এবং gawkবেশিরভাগ জায়গায় ডিফল্টরূপে উপলভ্য নয়।
অলি

6
ওপি বিশেষত একটি বিশ্রী সমাধানের জন্য জিজ্ঞাসা করেছিল, তাই আমি মনে করি এটি কোনও উত্তর নয়।
Joppe

6
@ জোপ আপনি যদি কোনও সমাধান না পান তবে আপনি কোনও বিশ্রী সমাধান দিতে পারবেন না। ৩ নং লাইনে আমি ব্যাখ্যা করেছি যে এডব্লু কে ক্যাপচারিং গ্রুপগুলিকে সমর্থন করে না এবং আমি একটি বিকল্প দিয়েছিলাম, যা ওপি দৃশ্যত প্রশংসা করেছিল কারণ এই উত্তর গৃহীত হয়েছিল। আমি কীভাবে এই প্রশ্নের উত্তর দিতে পারি?
পিটার টিলিম্যানস

335

গোকের সাহায্যে, আপনি প্রথম বন্ধনযুক্ত matchগোষ্ঠীগুলি ক্যাপচার করতে ফাংশনটি ব্যবহার করতে পারেন।

gawk 'match($0, pattern, ary) {print ary[1]}' 

উদাহরণ:

echo "abcdef" | gawk 'match($0, /b(.*)e/, a) {print a[1]}' 

আউটপুট cd

গাওকের নির্দিষ্ট ব্যবহারটি লক্ষ্য করুন যা প্রশ্নে বৈশিষ্ট্যটি কার্যকর করে।

পোর্টেবল বিকল্পের জন্য আপনি match()এবং এর সাথে একই ফলাফল অর্জন করতে পারেন substr

উদাহরণ:

echo "abcdef" | awk 'match($0, /b[^e]*/) {print substr($0, RSTART+1, RLENGTH-1)}'

আউটপুট cd


4
হ্যাঁ, জিএক্সএক্সএক্স বৈকল্পিকগুলিতে প্রচুর অতিরিক্ত জিএনইউ সদর্থকতা এবং শক্তি রয়েছে।
পিটার টিলিম্যানস

ব্যাসিবক্সে পাশাপাশি কাজ করে।
মিঃমাস

32

এটি আমার সমস্ত সময় প্রয়োজন তাই আমি এটির জন্য একটি বাশ ফাংশন তৈরি করেছি। এটি গ্লেন জ্যাকম্যানের উত্তরের উপর ভিত্তি করে।

সংজ্ঞা

এটি আপনার .bash_profile ইত্যাদিতে যুক্ত করুন

function regex { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'0'}']}'; }

ব্যবহার

ফাইলের প্রতিটি লাইনের জন্য ক্যাপচার করুন

$ cat filename | regex '.*'

ফাইলের প্রতিটি লাইনের জন্য 1 ম রেজেেক্স ক্যাপচার গ্রুপকে ক্যাপচার করুন

$ cat filename | regex '(.*)' 1

2
এটি ব্যবহার থেকে কীভাবে আলাদা grep -o?
bfontaine

@bfontaine grep -oক্যাপচার করা গ্রুপ আউটপুট করতে পারে ?
ওলে হার্স্টেট 15

1
@ OlleHärstedt না এটি পারেনি। এটি কেবল আপনার ব্যবহারের ক্ষেত্রে কভার করে যখন আপনার ক্যাপচার-গ্রুপ না থাকে। সেক্ষেত্রে এটি শৃঙ্খলিত দ্বারা কুৎসিত হয় grep -o
bfontaine

15

আপনি জিএনইউ অ্যাঙ্ক ব্যবহার করতে পারেন:

$ cat hta
RewriteCond %{HTTP_HOST} !^www\.mysite\.net$
RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]

$ gawk 'match($0, /.*(http.*?)\$/, m) { print m[1]; }' < hta
http://www.mysite.net/

12
+1 টি। এছাড়াও, যে কোনও জাঁকজমক সহ:awk 'match($0, /.*(http.*?)\$/) { print substr($0,RSTART,RLENGTH) }'
এড মর্টন


1
এড মর্টন: এটি যে উচ্চ-স্তরের উত্তরটি আমি বলব তার প্রাপ্য। সম্পাদনা: আহ ... এটি RewriteRule (.*) http://www.mysite.net/$আমার জন্য প্রিন্ট করে যা সাবগ্রুপের চেয়ে বেশি।
রায়পুম


4

আপনি কোনও এক্সটেনশন ছাড়াই ভ্যানিলা অ্যাডকেও ক্যাপচার করার অনুকরণ করতে পারেন। যদিও এটি স্বজ্ঞাত নয়:

পদক্ষেপ ১. কিছু চরিত্রের সাথে মেলে ঘিরে জেনসব ব্যবহার করুন যা আপনার স্ট্রিংয়ে উপস্থিত হয় না। পদক্ষেপ 2. চরিত্রের বিরুদ্ধে বিভক্ত ব্যবহার করুন। পদক্ষেপ 3. বিভক্ত অ্যারেতে অন্য প্রতিটি উপাদান আপনার ক্যাপচার গ্রুপ।

$ প্রতিধ্বনি 'আব সিবি বিজ্ঞাপন' | awk '{বিভাজন (জেনসুব (/ a ./, SUBSEP "&" SUBSEP, "g", $ 0), ক্যাপ, SUBSEP); মুদ্রণ ক্যাপ [2] "|" ক্যাপ [4]; } '
AB | বিজ্ঞাপন

3
আমি প্রায় নির্দিষ্ট যে gensubএকটি gawkনির্দিষ্ট ফাংশন। আপনি টাইপ করা হলে আপনার awk থেকে কী পাবেন awk --version; -?)। সবার জন্য শুভ কামনা.
শেল্টার

6
আমি পুরোপুরি নিশ্চিত যে জেনসব একটি গোক-ইসম, যদিও ব্যাসিবক্স এডকেরও রয়েছে। এই উত্তরটি gsub ব্যবহার করেও প্রয়োগ করা যেতে পারে, যদিও:echo 'ab cb ad' | awk '{gsub(/a./,SUBSEP"&"SUBSEP);split($0,cap,SUBSEP);print cap[2]"|"cap[4]}'
dubiousjim

3
জেনসুব () একটি গোকের এক্সটেনশন, গাকের ম্যানুয়ালটি স্পষ্টভাবে এটি বলে। অন্যান্য জঞ্জাল রূপগুলি এটি প্রয়োগ করতে পারে তবে এটি এখনও পসিক্স নয়। গোক - পসিক্স '{gsub (...)}' ব্যবহার করে দেখুন এবং এটি অভিযোগ করবে
MestreLion

2
@ মাস্টারলিয়ন, আপনার অর্থ এটি অভিযোগ করবে gawk --posix '{gensub(...)}'
dubiousjim

1
সত্ত্বেও আপনার সম্পর্কে ভুল ছিলে POSIX awk থাকার gensubফাংশন, আপনার উদাহরণ একটি খুব সীমিত দৃশ্যকল্প প্রয়োগ: পুরো প্যাটার্ন দলবদ্ধ করা হয়, এটা সব ভালো কিছু মেলে না key=(value)যখন আমি শুধুমাত্র বের করে আনতে চান valueঅংশ।
মীউ

2

আমি বাশ ফাংশন নিয়ে আসার সাথে কিছুটা লড়াই করেছি যা পিটার টিলেম্যানসের উত্তরটি জড়িয়ে দেয় তবে আমি এখানে যা এলাম তা এখানে:

ফাংশন regex {perl -n -e "/ $ 1 / && printf f"% s \ n \ "," '$ 1'}

নিম্নলিখিত নিয়মিত অভিব্যক্তি যুক্তিটির জন্য আমি opsb এর awk- ভিত্তিক বাশ ফাংশনটির চেয়ে আরও ভাল কাজ করেছি বলে আমি "এমএস" মুদ্রিত করতে চাই না।

'([0-9]*)ms$'

আমি এই সমাধানটিকে অগ্রাধিকার দিচ্ছি, যেহেতু আপনি গ্রুপটির যে অংশগুলি ক্যাপচারটি সীমাবদ্ধ রেখেছেন সেগুলিও বাদ দিতে পারেন। যাইহোক, কেউ কীভাবে এটি কাজ করে তা বর্ণিত করতে পারে? BASH এ সঠিকভাবে কাজ করার জন্য আমি এই পার্ল সিনট্যাক্সটি পেতে পারি না, কারণ আমি এটি খুব ভালভাবে বুঝতে পারি না - বিশেষত ডাবল / একক-উদ্ধৃতি চিহ্নগুলি$1
ডেমিস

এটি আমি এর আগে বা পরে কিছু করেছি না তবে এটি কী করছে তা ফিরে দেখানো দুটি স্ট্রাক্টকে বোঝানো হচ্ছে, প্রথম স্ট্রিংটি ডাবল উদ্ধৃতিতে রয়েছে (এই প্রথম স্ট্রিংটিতে এমবেডড ডাবল কোটস ব্যাকস্ল্যাশ সহ পালিয়েছে) এবং দ্বিতীয় স্ট্রিংটি একক উদ্ধৃতিতে রয়েছে । তারপরে সেই কনটেন্টেশনের ফলাফলটি পার্ল-ই-তে যুক্তি হিসাবে সরবরাহ করা হয়। এছাড়াও আপনার এটিও জানতে হবে যে প্রথম $ 1 (ডাবল কোটের মধ্যে একটি) ফাংশনের প্রথম যুক্তির সাথে প্রতিস্থাপিত হয়, যখন দ্বিতীয় $ 1 (একক উদ্ধৃতিতে থাকা) বাদ পড়ে যায় left এই উদাহরণটি
wETten

আমি দেখতে পাচ্ছি, এখন এটি কিছুটা বুদ্ধিমান। তাহলে পার্ল কমান্ডের মধ্যে কোথায় রেজেেক্স ম্যাচ / গ্রুপ ক্যাপচার সংজ্ঞা আছে? আমি দেখেছি আপনি লিখেছেন '([0-9]*)ms$'- এটি কি যুক্তি হিসাবে সরবরাহ করা হয় (এবং স্ট্রিংটি অন্য যুক্তি)? এবং এরপরে আউটপুট perl -eবাশের printfকমান্ডের মধ্যে beingোকানো হচ্ছে তখন, প্রতিস্থাপন করা %s, এটি কি ঠিক? ধন্যবাদ, আমি এটি ব্যবহার আশা করি।
ডেমিস

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