গ্রেপ, রেজেক্স বা পার্ল দিয়ে কোনও প্যাটার্ন অনুসরণ করে স্ট্রিং কীভাবে নিষ্কাশন করা যায়


90

আমার কাছে এমন একটি ফাইল রয়েছে যা দেখতে এরকম কিছু দেখাচ্ছে:

    <table name="content_analyzer" primary-key="id">
      <type="global" />
    </table>
    <table name="content_analyzer2" primary-key="id">
      <type="global" />
    </table>
    <table name="content_analyzer_items" primary-key="id">
      <type="global" />
    </table>

আমার উদ্ধৃতিগুলির মধ্যে যা কিছু অনুসরণ করা উচিত name=, অর্থাত্ content_analyzer, content_analyzer2এবং content_analyzer_items

আমি এটি একটি লিনাক্স বাক্সে করছি, সুতরাং সেড, পার্ল, গ্রেপ বা ব্যাশ ব্যবহার করে একটি সমাধান ঠিক আছে।


4
লাজুক হওয়ার দরকার নেই, এখানে স্বাগতম!
বেনোইট


দরকারী মন্তব্যের জন্য সবাইকে ধন্যবাদ। এক্সএমএলটি সঠিকভাবে ফর্ম্যাট না হওয়ার জন্য আমি ক্ষমা চাই ize সরলকরণের জন্য আমি কিছু ট্যাগ মুছলাম।
র‌্যাংলার

উত্তর:


167

যেহেতু আপনাকে ফলাফলটি অন্তর্ভুক্ত না করে আপনার সামগ্রীটি মেলে ফেলতে হবে (অবশ্যই মিলবে name=" তবে এটি পছন্দসই ফলাফলের অংশ নয়) শূন্য-প্রস্থের ম্যাচিং বা গ্রুপ ক্যাপচারের কোনও ফর্মের প্রয়োজন। এটি নিম্নলিখিত সরঞ্জামগুলির সাহায্যে সহজেই করা যায়:

পার্ল

পার্লের সাহায্যে আপনি n লাইন দ্বারা লুপ লুপ করতে বিকল্পটি ব্যবহার করতে এবং ক্যাপচারিং গোষ্ঠীর সাথে মেলে যদি মুদ্রণ করতে পারেন:

perl -ne 'print "$1\n" if /name="(.*?)"/' filename

জিএনইউ গ্রেপ

আপনার যদি গ্রেএন এর উন্নত সংস্করণ যেমন জিএনইউ গ্রেপ থাকে তবে আপনার কাছে -Pবিকল্পটি উপলভ্য হতে পারে । এই বিকল্পটি পার্লের মতো \Kরেজেজকে সক্ষম করবে, যা আপনাকে শর্টহ্যান্ড লুকের পিছনে ব্যবহার করার অনুমতি দেয় । এটি ম্যাচের অবস্থানটি পুনরায় সেট করবে, তাই এটি শূন্য-প্রস্থের আগে যে কোনও কিছুই।

grep -Po 'name="\K.*?(?=")' filename

o বিকল্প তোলে grep পুরো লাইনের পরিবর্তে শুধুমাত্র মিলেছে টেক্সট প্রিন্ট।

ভিম - পাঠ্য সম্পাদক

অন্য উপায় হ'ল সরাসরি একটি পাঠ্য সম্পাদক ব্যবহার করা। ভিমের সাথে, এটি সম্পাদনের বিভিন্ন উপায়গুলির মধ্যে একটি হ'ল লাইনগুলি ছাড়াই মুছে ফেলা name=এবং তারপরে ফলাফলগুলি লাইনগুলি থেকে সামগ্রীটি বের করা:

:v/.*name="\v([^"]+).*/d|%s//\1

স্ট্যান্ডার্ড গ্রেপ

যদি আপনার এই সরঞ্জামগুলিতে অ্যাক্সেস না থাকে তবে কোনও কারণে, স্ট্যান্ডার্ড গ্রেপ দিয়ে অনুরূপ কিছু অর্জন করা যেতে পারে। তবে আশেপাশে নজর না দিয়ে এর জন্য পরে কিছুটা পরিষ্কারের প্রয়োজন হবে:

grep -o 'name="[^"]*"' filename

ফলাফল সংরক্ষণের বিষয়ে একটি নোট

উপরের সমস্ত কমান্ডে ফলাফল পাঠানো হবে stdout। এটি মনে রাখা গুরুত্বপূর্ণ যে আপনি সবসময় এগুলি যুক্ত করে কোনও ফাইলে পাইপ দিয়ে এগুলি সংরক্ষণ করতে পারেন:

> result

কমান্ডের শেষে।


12
লুকোয়ারাউন্ডস (জিএনইউতে grep):grep -Po '.*name="\K.*?(?=".*)'
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত

@ ডেনিস উইলিয়ামসন, দুর্দান্ত। আমি সেই অনুযায়ী উত্তর আপডেট করেছি, তবে উভয়কেই .*রেখে দিয়েছি, আশা করি আপনি আমার সাথে রাগ করবেন না। আমি জিজ্ঞাসা করতে চাই, আপনি কি "লোভী" ব্যতীত লোভী ম্যাচের কোনও উপকারিতা দেখতে পাচ্ছেন "? এটিকে লড়াই হিসাবে গ্রহণ করবেন না, আমি কেবল কৌতূহলী এবং আমি একজন রেজেক্স বিশেষজ্ঞ নই। এছাড়াও, \Kটিপ, সত্যিই দুর্দান্ত। ধন্যবাদ ডেনিস
সিডিল

4
আমি রাগ করব কেন? ছাড়া .*, আপনি করতে পারেন grep -Po '(?<=name=").*?(?=")'\Kসাধারণভাবে সংক্ষেপে জন্য ব্যবহার করা যেতে পারে, কিন্তু এটা সত্যিই শুধুমাত্র দরকার যদি তার বামে ম্যাচ পরিবর্তনশীল দৈর্ঘ্য হল। এই জাতীয় ক্ষেত্রে, বর্ণমালা ব্যবহারের কারণটি মোটামুটি সুস্পষ্ট। Ungreedy অপারেশন একটু neater চেহারা ( [^"]*বনাম .*?এবং আপনার নোঙ্গর চরিত্র পুনরাবৃত্তি হবে না আমি গতি সম্পর্কে জানি না যে প্রসঙ্গের উপর অনেক নির্ভর করে, আমি মনে করি আমি আশা করি যে সহায়ক।।।।
পরবর্তী ঘোষণা না হওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

@ ডেনিস উইলিয়ামসন: অবশ্যই স্যার, এখানে অনেক সহায়ক তথ্য। আমি মনে করি যে \K( আমি এটির উপর গবেষণা করার পরে) রাখার এবং সরিয়ে দেওয়ার কারণটি .*একই ছিল: এটিকে সুন্দর দেখায় (সরল)। এবং আমি .*?কোথাও থেকে শিখেছি "traditionalতিহ্যবাহী উপায়" এর পরিবর্তে কখনও ব্যবহার করার কথা ভাবি নি । কিন্তু এখানে অ-লোভী সত্যই অর্থবোধ করে। ধন্যবাদ ডেনিস, শুভকামনা।
সিডিল

কমান্ড বর্ণনা করার জন্য +1। আপনি যদি রেইজেক্সের "[...]" অংশটি ব্যাখ্যা করার জন্য আপনার উত্তরটি আপডেট করতে পারেন তবে এটি প্রশংসা করবে।
মুক্তিদাতা


5

আপনি যদি পার্ল ব্যবহার করছেন তবে এক্সএমএল: এক্সএমএল :: সিম্পল , এক্সএমএল :: টুইগ , বা এক্সএমএল :: লিবএক্সএমএল পার্স করার জন্য একটি মডিউল ডাউনলোড করুন । চাকাটি পুনরায় উদ্ভাবন করবেন না।


4
উল্লেখ্য যে ওপি প্রদত্ত উদাহরণটি সুগঠিত নয় ( <type="global"উদাহরণস্বরূপ), তাই বেশিরভাগ এক্সএমএল পার্সার কেবল অভিযোগ করে মারা যায়।
বিভিআর

5

এইচটিএমএল পার্সার নিয়মিত প্রকাশের চেয়ে এই উদ্দেশ্যে ব্যবহার করা উচিত। একটি পার্ল প্রোগ্রাম যা ব্যবহার করেHTML::TreeBuilder :

কার্যক্রম

#!/usr/bin/env perl

use strict;
use warnings;

use HTML::TreeBuilder;

my $tree = HTML::TreeBuilder->new_from_file( \*DATA );
my @elements = $tree->look_down(
    sub { defined $_[0]->attr('name') }
);

for (@elements) {
    print $_->attr('name'), "\n";
}

__DATA__
<table name="content_analyzer" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
  <type="global" />
</table>

আউটপুট

content_analyzer
content_analyzer2
content_analyzer_items


2

এইচটিএমএল পরিপাটি এবং এক্সএমএল স্টারলেট ব্যবহার করে একটি সমাধান এখানে দেওয়া হয়েছে:

htmlstr='
<table name="content_analyzer" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
<type="global" />
</table>
'

echo "$htmlstr" | tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null |
sed '/type="global"/d' |
xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n

1

ওহো, সেড কমান্ডটি অবশ্যই পরিপাটি কমান্ডের আগে চলে যেতে হবে:

echo "$htmlstr" | 
sed '/type="global"/d' |
tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null |
xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n

0

যদি আপনার এক্সএমএলটির কাঠামো (বা সাধারণভাবে পাঠ্য) ঠিক করা থাকে তবে সবচেয়ে সহজ উপায়টি ব্যবহার করা হচ্ছে cut। আপনার নির্দিষ্ট ক্ষেত্রে:

echo '<table name="content_analyzer" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
  <type="global" />
</table>' | grep name= | cut -f2 -d '"'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.