পুরো রেখার দরকার নেই, নিয়মিত অভিব্যক্তি থেকে কেবল ম্যাচ


15

আমার কেবল একটি নিয়মিত অভিব্যক্তি থেকে ম্যাচটি নেওয়া দরকার:

$ cat myfile.txt | SOMETHING_HERE "/(\w).+/"

আউটপুট কেবল প্যারেনথেসিসের ভিতরে যা মিলছে তা হওয়া উচিত।

ভাববেন না যে আমি গ্রেপ ব্যবহার করতে পারি কারণ এটি সম্পূর্ণ লাইনের সাথে মেলে।

এটি আমাকে কীভাবে করবেন তা দয়া করে জানান let

উত্তর:


12

2 জিনিস:

  • @ ররি অনুসারে বলা হয়েছে, আপনার -oবিকল্পের প্রয়োজন , সুতরাং কেবল ম্যাচটি মুদ্রণ করা হয় (পুরো লাইনের পরিবর্তে)
  • এছাড়াও, -Pপার্ল নিয়মিত এক্সপ্রেশনগুলি ব্যবহার করার জন্য, আপনি বিকল্পটি নীচে রেখেছেন , যার মধ্যে সামনের দিকে তাকান(?= ) এবং পিছনে দেখুন এর মতো দরকারী উপাদানগুলি অন্তর্ভুক্ত রয়েছে(?<= ) , সেগুলি অংশগুলির জন্য সন্ধান করে তবে বাস্তবে এটি মেলে এবং মুদ্রণ করে না।

আপনি যদি চান যে প্যারেনসিসের কেবলমাত্র অংশটি মেলে:

grep -oP '(?<=\/\()\w(?=\).+\/)' myfile.txt

যদি ফাইলটিতে স্টিং থাকে তবে গ্রেপ /(a)5667/'এ' প্রিন্ট করবে, কারণ:

  • /(দ্বারা সন্ধান করা হয় \/\(, কিন্তু কারণ তারা পিছনে থাকে (?<= ) তাদের রিপোর্ট করা হয় না
  • aএর সাথে মিলেছে \wএবং এটি মুদ্রিত হয়েছে (কারণ -o)
  • )5667/বি <পাওয়া গেছে \).+\/, তবে তারা সামনের দিকে রয়েছে (?= ) বলে তাদের রিপোর্ট করা হয়নি

18

-oবিকল্পটি ব্যবহার করুন grep

উদাহরণ:

$ echo "foobarbaz" | grep -o 'b[aeiou]r'
bar

4
শুভ দুঃখ ... আমি কীভাবে বারবার sedপিছনে লড়াই করেছিলাম তা সম্পর্কে আপনার ধারণা আছে?
Insyte

10
গ্রেপ / এগ্রিপ-এর ও বিকল্পটি কেবল তার পুরো অনুরোধের সাথে মেলে যা পুরো নিয়মিত অভিব্যক্তির সাথে মেলে, কেবল তার (যেমন) যা চেয়েছিল তেমন নয়।
কাইল ব্র্যান্ড্ট

1
তবে যাইহোক :-)
কাইল ব্র্যান্ড্ট

2
@ কাইলব্র্যান্ড: কেবলমাত্র একটি অংশের সাথে মেলে (যেমন: প্যারেনেস) সামনের দিকে তাকিয়ে বা পিছনের দিকে তাকিয়ে বাকীটি চিহ্নিত করা সম্ভব: (? <=) এবং (? =)
ডাঃ ইয়াক

7
    sed -n "s/^.*\(captureThis\).*$/\1/p"

-n      don't print lines
s       substitute
^.*     matches anything before the captureThis 
\( \)   capture everything between and assign it to \1 
.*$     matches anything after the captureThis 
\1      replace everything with captureThis 
p       print it

4

যদি আপনি কেবল প্রথম বন্ধনীতে যা চান তা চাইলে আপনার এমন কিছু দরকার যা সাব ম্যাচগুলি ক্যাপচার সমর্থন করে (নামযুক্ত বা সংখ্যাযুক্ত ক্যাপচারিং গ্রুপ)। আমি মনে করি না গ্রেপ বা এগ্রিপ এটি করতে পারে, পার্ল এবং সেড পারে। উদাহরণস্বরূপ, পার্ল সহ:

Foo নামক কোনও ফাইলের যদি এতে একটি লাইন থাকে তবে:

/adsdds      /

এবং তুমি কর:

perl -nle 'print $1 if /\/(\w).+\//' foo

চিঠিটি ফেরত দেওয়া হয়েছে। আপনি চাইলেও তা হতে পারে না। আপনি কী মিলানোর চেষ্টা করছেন তা যদি আমাদের জানান তবে আপনি আরও ভাল সহায়তা পেতে পারেন। Parent 1 হ'ল প্রথম বন্ধনে প্রথম ক্যাপচার করা। Set 2 হবে দ্বিতীয় সেট ইত্যাদি etc.


আমি কেবল বন্ধনীতে যা আছে তা মেলানোর চেষ্টা করছিলাম। এটি পার্ল বা পিএইচপি স্ক্রিপ্টে পাস করার মতো উত্তর হতে পারে।
অ্যালেক্স এল

4

আপনি শেল ছাড়াও আপনার প্রশ্নটিকে বাশ হিসাবে ট্যাগ করার কারণে , গ্রেপের পাশে আরও একটি সমাধান রয়েছে :

=~পার্লের মতো অপারেটরটি ব্যবহার করে, ভার্সন 3.0.০ থেকে বাশের নিজস্ব নিয়মিত প্রকাশের ইঞ্জিন রয়েছে ।

এখন, নিম্নলিখিত কোড দেওয়া:

#!/bin/bash
DATA="test <Lane>8</Lane>"

if [[ "$DATA" =~ \<Lane\>([[:digit:]]+)\<\/Lane\> ]]; then
        echo $BASH_REMATCH
        echo ${BASH_REMATCH[1]}
fi
  • নোট করুন যে আপনাকে সমস্ত এক্সটেনশানগুলি পেতে bashকেবল এটি হিসাবে চালিত করতে হবে নাsh
  • $BASH_REMATCH সম্পূর্ণ নিয়মিত প্রকাশের সাথে মিলে যাওয়া হিসাবে পুরো স্ট্রিংটি দেবে <Lane>8</Lane>
  • ${BASH_REMATCH[1]} 1 ম গ্রুপের সাথে মিলে যাওয়া অংশটি কেবল এইভাবে দেবে 8

প্রিয় @ ড্রয়াক, আমি আশা করি আপনি এখানে
এক্সএএমএলকে রেইগেক্স

এটা আরও খারাপ। এসএনএসপ্যারালাল দ্রুত লার্জস্কেল অ্যালিগনেমেন্ট সফ্টওয়্যার >দ্বারা প্রকাশিত হিসাবে আমি এক্সএমএল এবং ফাসটা ডেটার (যা উভয়ই সম্পূর্ণ ভিন্ন উদ্দেশ্যে প্রতীক ব্যবহার করে ) এর একটি ভয়াবহ মিশ্রণ পার্স করছি । অবশ্যই উভয় ফর্ম্যাট কোনও প্রস্থান ছাড়াই আন্তঃবিষ্ট করা হয়। সুতরাং এটিতে কিছু স্ট্যান্ডার্ড এক্সএমএল লাইব্রেরি নিক্ষেপ করা অসম্ভব। এবং আমি কোডের এই পর্যায়ে বাশ রেইগেক্স ব্যবহার করছি কারণ আমার কেবলমাত্র কয়েকটি ডেটা বের করতে হবে এবং এই গন্ডগোলের জন্য ডেডিকেটেড পার্সার লেখার চেয়ে 2 রেজেেক্স আমার জন্য কাজটি আরও ভাল করে তুলবে। # লাইফইনবায়োইনফরম্যাটিকস
ড্রয়াক

অন্য কথায়: একটি বিন্দু যেখানে একক সংখ্যা বের করা পুরো এক্সএমএল টাঙ্গো নাচের চেয়ে রেগেক্স রাথানের সাথে করা সহজ
ড্রয়াক

হাহ, গোছা! :)
junas.fi

2

ধরে নিচ্ছি ফাইলটি রয়েছে:

$ cat file
Text-here>xyz</more text

আর তুমি অক্ষর (গুলি) মধ্যে চান >এবং </, হয় আপনি ব্যবহার করতে পারেন:

grep -oP '.*\K(?<=>)\w+(?=<\/)' file
sed -nE 's:^.*>(\w+)</.*$:\1:p' file
awk '{print(gensub("^.*>(\\w+)</.*$","\\1","g"))}' file
perl -nle 'print $1 if />(\w+)<\//' file

সকলেই একটি স্ট্রিং "xyz" মুদ্রণ করবে।

আপনি যদি এই লাইনের অঙ্কগুলি ক্যাপচার করতে চান:

$ cat file
Text-<here>1234</text>-ends

grep -oP '.*\K(?<=>)[0-9]+(?=<\/)' file
sed -E 's:^.*>([0-9]+)</.*$:\1:' file
awk '{print(gensub(".*>([0-9]+)</.*","\\1","g"))}' file
perl -nle 'print $1 if />([0-9]+)<\//' file


আমার কাছে গুরুত্বপূর্ণটি ছিল উপলব্ধি করা \ d সেডের সাথে কাজ করে না। আপনি এখানে [0-9] ব্যবহার করার একটি কারণ রয়েছে। :)
user27432

@ user27423 এটা না, কিন্তু POSIX চরিত্র শ্রেণীর ( বেদনাদায়ক পড়া , মনোরম পড়া ) করুন: echo 'Text-<here>1234</text>-ends' | sed -E 's|.*>([[:digit:]]+)<.*|\1|'। কিছু ক্ষেত্রে (যেমন [0-9]বনাম [[:digit:]]) এগুলি সুশৃঙ্খলতা সহায়তা করে না, অন্যথায় আমি মনে করি তারা করে (যেমন [ \t\n\r\f\v]বনাম [:space:])।
স্যামুয়েল হারমার

0

এটি আপনি যা অনুরোধ করছেন তা সম্পাদন করবে, তবে আমি মনে করি না যে এটি আপনি যা চান তা সত্যই। আমি করা .*Regex ম্যাচের আগে কিছু আপ খেতে সামনে, কিন্তু যে একটি অর্থগৃধ্নু অপারেশন তাই এই শুধুমাত্র উপান্ত্য ম্যাচ হয়, \wস্ট্রিং অক্ষর।

নোট করুন যে আপনার প্যারেনস এবং এর থেকে বাঁচতে হবে +

sed 's/.*\(\w\).\+/\1/' myfile.txt
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.