দুটি শব্দের মধ্যে পাঠ্য আহরণ করতে সেড / গ্রেপ কীভাবে ব্যবহার করবেন?


134

আমি একটি স্ট্রিং আউটপুট দেওয়ার চেষ্টা করছি যাতে দুটি স্ট্রিংয়ের মধ্যে দুটি শব্দ থাকে

ইনপুট:

"Here is a String"

আউটপুট:

"is a"

ব্যবহার:

sed -n '/Here/,/String/p'

শেষ পয়েন্টগুলি অন্তর্ভুক্ত করে তবে আমি সেগুলি অন্তর্ভুক্ত করতে চাই না।


8
ইনপুট হলে ফলাফল কী হওয়া উচিত Here is a Here String? নাকি I Hereby Dub Thee Sir Stringy?
ঘোটি

5
অবগতির জন্য। আপনার কমান্ডটির অর্থ এখানে শব্দটি রয়েছে এমন লাইনের এবং স্ট্রিং শব্দটির সাথে থাকা রেখার মধ্যে থাকা সমস্ত কিছু মুদ্রণ করা - আপনি যা চান তা নয়।
হাই ভু

অন্যান্য সাধারণ sedFAQ হ'ল "আমি কীভাবে নির্দিষ্ট রেখার মাঝে পাঠ্য বের করতে পারি"; এই হল stackoverflow.com/questions/16643288/...
tripleee

উত্তর:


109
sed -e 's/Here\(.*\)String/\1/'

2
ধন্যবাদ! "যদি এখানে একটি" একটি স্ট্রিং রয়েছে "এর মধ্যে" একটি হয় "এবং" স্ট্রিং "এর মধ্যে সমস্ত কিছু খুঁজে পেতে চাই তবে কী হবে? (সেড-ই এর / একটি (। *) স্ট্রিং / \ 1 / '?
ব্যবহারকারী 1190650

5
@ ব্যবহারকারী 1190650 আপনি যদি "এখানে একটি" দেখতে চান তবে এটি কাজ করবে। আপনি এটি পরীক্ষা করতে পারেন: echo "Here is a one is a String" | sed -e 's/one is\(.*\)String/\1/'। আপনি শুধু মধ্যে অংশ এবং "স্ট্রিং" "এক" চান, তাহলে আপনি Regex পুরো লাইন মেলে করা প্রয়োজন: sed -e 's/.*one is\(.*\)String.*/\1/'। সেডে, s/pattern/replacement/"প্রতিটি লাইনে 'প্যাটার্নের' বিকল্প 'প্রতিস্থাপন' বলুন। এটি কেবল "প্যাটার্ন" এর সাথে মেলে এমন কোনও কিছু পরিবর্তন করবে, তাই আপনি যদি এটি পুরো লাইনটি প্রতিস্থাপন করতে চান তবে আপনাকে "প্যাটার্ন" পুরো লাইনের সাথে মেলে তৈরি করতে হবে।
ব্রায়ান ক্যাম্পবেল

9
ইনপুটটি হলে এই বিরতি ঘটেHere is a String Here is a String
জে ডি

1
কেসের সমাধান দেখতে দুর্দান্ত লাগবে: "এখানে একটি ব্লাহ ব্লাহ স্ট্রিং এখানে 1 ব্লা ব্লাহ স্ট্রিং এখানে 2 টি ব্লাশ ব্ল্যাশ স্ট্রিং রয়েছে" আউটপুট এখানে এবং স্ট্রিংয়ের মধ্যে কেবল প্রথম স্ট্রিং বেছে নিতে হবে "
জে ডি

1
@ জায়েড সেড অ লোভী মিলকে সমর্থন করে না, কিছু প্রস্তাবিত বিকল্পের জন্য এই প্রশ্নটি দেখুন ।
ব্রায়ান ক্যাম্পবেল

179

জিএনইউ গ্রেপ ইতিবাচক ও নেতিবাচক চেহারা এবং এগিয়ে ফিরে যেতে সহায়তা করতে পারে: আপনার ক্ষেত্রে আদেশটি হ'ল:

echo "Here is a string" | grep -o -P '(?<=Here).*(?=string)'

যদি এর একাধিক ঘটনা ঘটে থাকে Hereএবং stringআপনি প্রথম বা Hereশেষের থেকে মিল করতে চান stringবা পৃথকভাবে সেগুলি মেলাতে চান তা চয়ন করতে পারেন । রেজেক্সের ক্ষেত্রে এটি লোভী ম্যাচ (প্রথম কেস) বা অ-লোভী মিল (দ্বিতীয় কেস) হিসাবে ডাকা হয়

$ echo 'Here is a string, and Here is another string.' | grep -oP '(?<=Here).*(?=string)' # Greedy match
 is a string, and Here is another 
$ echo 'Here is a string, and Here is another string.' | grep -oP '(?<=Here).*?(?=string)' # Non-greedy match (Notice the '?' after '*' in .*)
 is a 
 is another 

31
নোট করুন যে জিএনইউ গ্রেপের -Pবিকল্পগুলি grep* বিএসডি অন্তর্ভুক্ত নেই বা যে কোনও এসভিআর 4 (সোলারিস, ইত্যাদি) এর সাথে অন্তর্ভুক্ত রয়েছে। ফ্রিবিএসডি-তে আপনি devel/pcreপোর্টটি ইনস্টল করতে পারেন যা অন্তর্ভুক্ত রয়েছে pcregrep, যা পিসিআরই সমর্থন করে (এবং চেহারা এগিয়ে / পিছনে) look ওএসএক্স-এর পুরানো সংস্করণগুলি জিএনইউ গ্রেপ ব্যবহার করেছে, তবে ওএসএক্স ম্যাভেরিক্স-এ -Pফ্রিবিএসডি-র সংস্করণ থেকে উদ্ভূত হয়েছে, যা বিকল্পটি অন্তর্ভুক্ত করে না।
ঘোটি

1
হাই, আমি কীভাবে কেবল পৃথক সামগ্রী বের করব?
দুর্গেশ সুথার

4
এটি কাজ করে না কারণ যদি আপনার শেষ স্ট্রিং "স্ট্রিং" একাধিকবার ঘটে থাকে তবে এটি শেষ ঘটনাটি পাবে, পরবর্তী ঘটনাটি নয়।
বাটল বুটকাস

6
ক্ষেত্রে Here is a string a string, উভয় " is a " এবং " is a string a "বৈধ উত্তর (উদ্ধৃতি এড়িয়ে যান), প্রশ্ন প্রয়োজনীয়তা হিসাবে হয়। এটা আপনি এই এক যার উপর নির্ভর করে আপনি চান এবং তারপর উত্তর তদনুসারে ভিন্ন হতে পারে। যাইহোক, আপনার প্রয়োজনের জন্য, এটি কাজ করবে:echo "Here is a string a string" | grep -o -P '(?<=Here).*?(?=string)'
আনিসনে

2
@ বিএনডি, আপনাকে পিসিগ্রিপ -এর বহু-লাইন অনুসন্ধান বৈশিষ্ট্য সক্ষম করতে হবে । echo $'Here is \na string' | grep -zoP '(?<=Here)(?s).*(?=string)'
আনিসনে

58

গৃহীত উত্তর পূর্বে Hereবা পরে যে পাঠ্য থাকতে পারে তা সরিয়ে দেয় না String। এটা হবে:

sed -e 's/.*Here\(.*\)String.*/\1/'

মূল পার্থক্য হ'ল .*আগে Hereএবং পরে অবিলম্বে সংযোজন String


আপনার উত্তর আশাব্যঞ্জক। যদিও একটি ইস্যু। একই লাইনে একাধিক স্ট্রিং থাকলে আমি কীভাবে এটি প্রথম দেখা স্ট্রিংয়ে বের করতে পারি? ধন্যবাদ
মিয়া আসবাত আহমদ

@ মিয়ানআসবাতআহমাদ আপনি নিখরচায় এবং অ-লোভী (বা অলস) *মধ্যে কোয়ান্টিফায়ার তৈরি করতে চান । যাইহোক, সেড দ্বারা ব্যবহৃত রেজেেক্সের ধরণটি অলস কোয়ানটিফায়ারগুলিকে সমর্থন করে না (তার পরপরইHereString?.* রেজেেক্সের ধরণটি এই স্ট্যাকওভারফ্লো প্রশ্ন অনুসারে ) । সাধারণত একটি অলস কোয়ান্টিফায়ার আপনি শুধু সবকিছু টোকেন ছাড়া আপনি মেলে চাইনি বিরুদ্ধে মেলে দিবে বাস্তবায়ন, কিন্তু এই ক্ষেত্রে, সেখানে কেবলমাত্র একটি টোকেন, পরিবর্তে তার একটি পুরো স্ট্রিং, নয় String
হুইলারের


দুর্ভাগ্যক্রমে স্ট্রিংয়ের লাইন বিরতি থাকলে এটি কাজ করে না
উইটালো বেনিসিও

এটা অনুমিত হয় না। .লাইন বিরতি মেলে না। আপনি যদি লাইন ব্রেকগুলি মেলাতে চান তবে আপনি প্রতিস্থাপন করতে পারেন. মতো কিছু দিয়ে করতে পারেন [\s\s]
হুইলারের

35

আপনি একা বাশে স্ট্রিং স্ট্রিপ করতে পারেন :

$ foo="Here is a String"
$ foo=${foo##*Here }
$ echo "$foo"
is a String
$ foo=${foo%% String*}
$ echo "$foo"
is a
$

এবং আপনার যদি পিসিআরই অন্তর্ভুক্ত একটি জিএনইউ গ্রেপ থাকে তবে আপনি একটি শূন্য প্রস্থের প্রতিলিপি ব্যবহার করতে পারেন:

$ echo "Here is a String" | grep -Po '(?<=(Here )).*(?= String)'
is a

কেন এই পদ্ধতি এত ধীর? এই পদ্ধতিটি ব্যবহার করে একটি বৃহত এইচটিএমএল পৃষ্ঠা ফেলা করার সময় এটি 10 ​​সেকেন্ডের মতো লাগে।
অ্যাডাম জনস

@ অ্যাডাম জনস, কোন পদ্ধতি? পিসিআরই এক? পিসিআরই পার্স করার পক্ষে মোটামুটি জটিল, তবে 10 সেকেন্ডটি চরম বলে মনে হচ্ছে। যদি আপনি উদ্বিগ্ন হন তবে আমি আপনাকে উদাহরণ কোড সহ একটি প্রশ্ন করার পরামর্শ দিচ্ছি এবং বিশেষজ্ঞরা কী বলছেন তা দেখুন।
ঘোটি

আমি মনে করি এটি আমার পক্ষে খুব ধীর ছিল কারণ এটি একটি ভেরিয়েবলের মধ্যে খুব বড় এইচটিএমএল ফাইলের উত্স ধারণ করে। যখন আমি ফাইলগুলিতে বিষয়বস্তু লিখেছি এবং তারপরে ফাইলটি পার্সিং করেছি গতি নাটকীয়ভাবে বেড়েছে।
অ্যাডাম জনস

22

জিএনইউ অ্যাওকের মাধ্যমে,

$ echo "Here is a string" | awk -v FS="(Here|string)" '{print $2}'
 is a 

সঙ্গে, grep -P( Perl-regexp ) প্যারামিটার সমর্থন \K, যা পূর্বে মিলেছে অক্ষর খারিজ সাহায্য করে। আমাদের ক্ষেত্রে, আগের Hereম্যাচ করা স্ট্রিংটি তাই চূড়ান্ত আউটপুট থেকে ফেলে দেওয়া হয়েছিল।

$ echo "Here is a string" | grep -oP 'Here\K.*(?=string)'
 is a 
$ echo "Here is a string" | grep -oP 'Here\K(?:(?!string).)*'
 is a 

আপনি যদি আউটপুটটি দেখতে চান is aতবে নীচে চেষ্টা করতে পারেন,

$ echo "Here is a string" | grep -oP 'Here\s*\K.*(?=\s+string)'
is a
$ echo "Here is a string" | grep -oP 'Here\s*\K(?:(?!\s+string).)*'
is a

এই জন্য কাজ করে না: echo "Here is a string dfdsf Here is a string" | awk -v FS="(Here|string)" '{print $2}', এটি শুধুমাত্র ফেরৎ is aপরিবর্তে হওয়া উচিত is a is a@Avinash রাজ
Alper

20

আপনার যদি বহু মাল্টি-লাইনের সংস্থান সহ একটি দীর্ঘ ফাইল থাকে তবে প্রথমে সংখ্যা লাইনগুলি প্রিন্ট করা কার্যকর:

cat -n file | sed -n '/Here/,/String/p'

3
ধন্যবাদ! এটিই একমাত্র সমাধান যা আমার ক্ষেত্রে কাজ করেছিল (একাধিক লাইন পাঠ্য ফাইল, কোনও লাইন ব্রেক ছাড়াই একক স্ট্রিংয়ের চেয়ে বেশি)। স্পষ্টতই, লাইন নম্বর ছাড়াই এটির জন্য, -nবিকল্পটি catবাদ দিতে হবে।
জেফরি লেবোস্কি

... যে ক্ষেত্রে catপুরোপুরি বাদ দেওয়া যেতে পারে; sedকীভাবে কোনও ফাইল বা স্ট্যান্ডার্ড ইনপুট পড়তে হয় তা জানে।
ট্রিপলি

9

এটি আপনার (জিএনইউ সেড) কাজ করতে পারে:

sed '/Here/!d;s//&\n/;s/.*\n//;:a;/String/bb;$!{n;ba};:b;s//\n&/;P;D' file 

এটি একটি নতুন লাইনে দুটি চিহ্নিতকারী (এই উদাহরণস্বরূপ Hereএবং String) এর মধ্যে পাঠ্যের প্রতিটি উপস্থাপনা উপস্থাপন করে এবং পাঠ্যের মধ্যে নতুন লাইনের সংরক্ষণ করে।


7

উপরের সমস্ত সমাধানের ঘাটতি রয়েছে যেখানে স্ট্রিংয়ের অন্য কোথাও সর্বশেষ অনুসন্ধানের পুনরাবৃত্তি করা হয়। আমি ব্যাশ ফাংশনটি লেখার পক্ষে সবচেয়ে ভাল পেয়েছি।

    function str_str {
      local str
      str="${1#*${2}}"
      str="${str%%$3*}"
      echo -n "$str"
    }

    # test it ...
    mystr="this is a string"
    str_str "$mystr" "this " " string"

6

আপনি দুটি কমান্ড ব্যবহার করতে পারেন

$ echo "Here is a String" | sed 's/.*Here//; s/String.*//'
 is a 

এছাড়াও কাজ করে

$ echo "Here is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
 is a

$ echo "Here is a StringHere is a StringHere is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
 is a 

6

বুঝতে sedকমান্ড , আমাদের এটি ধাপে ধাপে তৈরি করতে হবে।

এখানে আপনার মূল পাঠ্য

user@linux:~$ echo "Here is a String"
Here is a String
user@linux:~$ 

এর মধ্যে ubstition বিকল্পের Hereসাথে স্ট্রিংটি সরিয়ে দেওয়ার চেষ্টা করিssed

user@linux:~$ echo "Here is a String" | sed 's/Here //'
is a String
user@linux:~$ 

এই মুহুর্তে, আমি বিশ্বাস করি আপনি সরাতে সক্ষম হবে Stringপাশাপাশি

user@linux:~$ echo "Here is a String" | sed 's/String//'
Here is a
user@linux:~$ 

তবে এটি আপনার পছন্দসই আউটপুট নয়।

দুটি সেড কমান্ড একত্রিত করতে, -eবিকল্পটি ব্যবহার করুন

user@linux:~$ echo "Here is a String" | sed -e 's/Here //' -e 's/String//'
is a
user@linux:~$ 

আশাকরি এটা সাহায্য করবে


4

আপনি ব্যবহার করতে পারেন \1( http://www.grymoire.com/Unix/Sed.html#uh-4 দেখুন ):

echo "Hello is a String" | sed 's/Hello\(.*\)String/\1/g'

বন্ধনীগুলির মধ্যে থাকা সামগ্রীগুলি সংরক্ষণ করা হবে \1


এটি এর মধ্যে কিছু আউটপুট পরিবর্তে স্ট্রিংগুলি সরিয়ে দেয়। সেড কমান্ডে "হ্যালো" সাথে "হ্যালো" মুছে ফেলার চেষ্টা করুন এবং এটি "হ্যালো এ" আউটপুট দেবে
জোনাথন

1

সমস্যা। আমার সঞ্চিত ক্লজ মেল বার্তাগুলি নীচে মোড়ানো হয়েছে এবং আমি সাবজেক্ট লাইনগুলি বের করার চেষ্টা করছি:

Subject: [SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular
 link in major cell growth pathway: Findings point to new potential
 therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is
 Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as
 a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway
 identified [Lysosomal amino acid transporter SLC38A9 signals arginine
 sufficiency to mTORC1]]
Message-ID: <20171019190902.18741771@VictoriasJourney.com>

এই থ্রেডে প্রতি এ 2, দুটি শব্দের মধ্যে পাঠ্য নিষ্কাশনের জন্য সেড / গ্রেপ কীভাবে ব্যবহার করবেন? নীচের প্রথম অভিব্যক্তিটি যতক্ষণ না ম্যাচ করা পাঠ্যে নতুন লাইন না থাকে: "কাজ করে":

grep -o -P '(?<=Subject: ).*(?=molecular)' corpus/01

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key

তবে, অসংখ্য বৈকল্পিক ( .+?; /s; ...) চেষ্টা করেও আমি এগুলি কাজ করতে পারি না:

grep -o -P '(?<=Subject: ).*(?=link)' corpus/01
grep -o -P '(?<=Subject: ).*(?=therapeutic)' corpus/01
etc.

সমাধান ঘ।

প্রতি বিভিন্ন লাইন দুটি স্ট্রিং মধ্যে এক্সট্র্যাক্ট টেক্সট

sed -n '/Subject: /{:a;N;/Message-ID:/!ba; s/\n/ /g; s/\s\s*/ /g; s/.*Subject: \|Message-ID:.*//g;p}' corpus/01

যা দেয়

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular link in major cell growth pathway: Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]                              

সমাধান ২। *

প্রতি সেড ব্যবহার করে আমি কীভাবে একটি নতুন লাইন () n) প্রতিস্থাপন করতে পারি?

sed ':a;N;$!ba;s/\n/ /g' corpus/01

একটি স্থানের সাথে নিউলাইনগুলি প্রতিস্থাপন করবে।

A2 এর সাথে শৃঙ্খলাবদ্ধ করে কীভাবে দুটি শব্দের মধ্যে পাঠ্য আহরণ করতে সেড / গ্রেপ ব্যবহার করবেন? , আমরা পেতে:

sed ':a;N;$!ba;s/\n/ /g' corpus/01 | grep -o -P '(?<=Subject: ).*(?=Message-ID:)'

যা দেয়

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular  link in major cell growth pathway: Findings point to new potential  therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is  Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as  a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway  identified [Lysosomal amino acid transporter SLC38A9 signals arginine  sufficiency to mTORC1]] 

এই রূপটি ডাবল স্পেসগুলি সরিয়ে দেয়:

sed ':a;N;$!ba;s/\n/ /g; s/\s\s*/ /g' corpus/01 | grep -o -P '(?<=Subject: ).*(?=Message-ID:)'

দান

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular link in major cell growth pathway: Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]

1
চমৎকার অ্যাডভেঞ্চার :))
আলেকজান্দ্রু-মিহাই মানোলেস্কু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.