শেল স্ক্রিপ্টে অন্য স্ট্রিংয়ের জন্য একটি স্ট্রিং প্রতিস্থাপন করুন


820

আমার "আমি সুজি এবং বিয়ে" পছন্দ করি এবং আমি "সুজি" কে "সারা" তে পরিবর্তন করতে চাই।

#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...

ফলাফলটি অবশ্যই এর মতো হওয়া উচিত:

firstString="I love Sara and Marry"

15
আমি সুজিকে আস্তে করে নামিয়ে দিয়ে শুরু করব। :)
কোডনিফার

এটা তুমি না, আমি এটা! সুজি
গুডস্পিএনপি

উত্তর:


1357

কোনও প্রদত্ত স্ট্রিং সহ কোনও প্যাটার্নের প্রথম উপস্থিতিটি প্রতিস্থাপন করতে :${parameter/pattern/string}

#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"    
# prints 'I love Sara and Marry'

সমস্ত উপস্থিতি প্রতিস্থাপন করতে , ব্যবহার করুন :${parameter//pattern/string}

message='The secret code is 12345'
echo "${message//[0-9]/X}"           
# prints 'The secret code is XXXXX'

(এই নথিভুক্ত করা ব্যাশ রেফারেন্স ম্যানুয়াল , §3.5.3 "শেল প্যারামিটার সম্প্রসারণ" ।)

নোট করুন যে এই বৈশিষ্ট্যটি পসিক্স দ্বারা নির্দিষ্ট করা হয়নি - এটি একটি বাশ এক্সটেনশান - সুতরাং সমস্ত ইউনিক্স শেল এটি প্রয়োগ করে না। সম্পর্কিত পসিএক্স ডকুমেন্টেশনের জন্য ওপেন গ্রুপের প্রযুক্তিগত স্ট্যান্ডার্ড বেসের বিশেষ উল্লেখ, ইস্যু 7 , শেল এবং ইউটিলিটিস ভলিউম, .62.6.2 "প্যারামিটার সম্প্রসারণ" দেখুন


3
@রুখ আমি কীভাবে কোনও শর্ত দিয়ে এই বিবৃতিটি লিখি। আমি যদি সুজি প্রতিস্থাপন করতে চাই বা নতুন স্ট্রিং দিয়ে বিয়ে করব।
প্রিয়থাম ৫১

3
@ প্রিয়তম ৫১: এর জন্য কোনও অন্তর্নির্মিত বৈশিষ্ট্য নেই। কেবল একটি, অন্যটি প্রতিস্থাপন করুন।
রুখ

4
@ বু: না, কারণ \nসেই প্রসঙ্গে নিজেকে প্রতিনিধিত্ব করবে, কোনও নতুন লাইন নয়। আমার কাছে এখনই পরীক্ষার জন্য বাশ হস্ত নেই, তবে আপনার মতো কিছু লিখতে সক্ষম হওয়া উচিত $STRING="${STRING/$'\n'/<br />}"। (যদিও আপনি সম্ভবত চান STRING//- প্রতিস্থাপন সব - শুধু বদলে STRING/।)
ruakh

25
স্পষ্টতই, যেহেতু এটি আমাকে কিছুটা বিভ্রান্ত করেছে, প্রথম অংশটি একটি পরিবর্তনশীল রেফারেন্স হতে হবে। আপনি করতে পারবেন না echo ${my string foo/foo/bar}। আপনার প্রয়োজনinput="my string foo"; echo ${input/foo/bar}
হেনরিক এন

2
@ এমগুট: এই উত্তরটি প্রাসঙ্গিক ডকুমেন্টেশনের সাথে লিঙ্ক করে। ডকুমেন্টেশন নিখুঁত নয় - উদাহরণস্বরূপ, //সরাসরি উল্লেখ করার পরিবর্তে এটি "কীভাবে প্যাটার্নটি ' /'" দিয়ে শুরু হয় তা ঘটে যা উল্লেখ করে (যা এমনকি সঠিক নয়, যেহেতু বাক্যটির বাকী /অংশ ধরে নেওয়া হয় যে অতিরিক্তটি আসলে অংশের অংশ নয় প্যাটার্ন) - তবে আমি এর চেয়ে ভাল উত্সটি জানি না।
রুখ

208

এটি পুরোপুরি বাশ স্ট্রিং ম্যানিপুলেশন দ্বারা সম্পন্ন করা যেতে পারে:

first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}

এটি কেবল প্রথম ঘটনাটি প্রতিস্থাপন করবে; সেগুলি প্রতিস্থাপন করতে, প্রথম স্ল্যাশ দ্বিগুণ করুন:

first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"

9
গ্লোবাল রিপ্লেসমেন্ট বিকল্পের সাহায্যে গৃহীত একটিকে সম্পাদনার পরিবর্তে গৃহীত উত্তরটিকে সদৃশ করে এমন একটি উত্তর থাকার কী আছে? এবং যোগ করা হচ্ছে যে রেগেক্সপ্স সমর্থিত, যখন এটি রয়েছে। এবং "খারাপ প্রতিস্থাপন" কী হচ্ছে তা ব্যাখ্যা করে। আপনার যথেষ্ট পয়েন্ট রয়েছে, @ কেভিন :)
ড্যান ড্যাসক্লেস্কু

6
দেখা যাচ্ছে যে তারা দুজনেই ঠিক একই মুহুর্তে উত্তর দিয়েছে: ও
জ্যামি হাবার

76

ড্যাশের জন্য পূর্ববর্তী সমস্ত পোস্ট কাজ করছে না

পসিক্স shসুসংগত সমাধানটি হ'ল:

result=$(echo "$firstString" | sed "s/Suzi/$secondString/")

1
আমি এটি পেয়েছি: cho প্রতিধ্বনি $ (প্রতিধ্বনি $ প্রথম স্ট্রিং | সেড / সুজি / $ সেকেন্ড স্ট্রিং / জি ') আমি ভালোবাসি St দ্বিতীয় স্ট্রিং এবং বিবাহ
Qstnr_La

2
: পরিবর্তনশীল প্রতিকল্পন জন্য ডবল কোট ব্যবহার @Qstnr_Laresult=$(echo $firstString | sed "s/Suzi/$secondString/g")
EMC

1
পাশাপাশি চলকটিতে আউটপুট কীভাবে প্রদর্শন করা যায় তার জন্য প্লাস 1। ধন্যবাদ!
শেফ ফেরাউন

2
আমি একক উদ্ধৃতি স্থির করেছি এবং echoযুক্তির চারপাশে হারিয়ে যাওয়া উক্তিগুলিও যুক্ত করেছি । এটি সাধারণ স্ট্রিংয়ের সাথে উদ্ধৃতি না দিয়ে ছদ্মবেশে কাজ করে তবে সহজেই কোনও অনিয়ন্ত্রিত ইনপুট স্ট্রিং (অনিয়মিত ফাঁক, শেল মেটাচার্যাক্টর ইত্যাদি) ভেঙে যায়।
ট্রিপলি

Sh (এডাব্লুএস কোডবিল্ড / উবুন্টু এসএইচ) আমি দেখতে পেয়েছি যে আমার শেষের দিকে একক স্ল্যাশ দরকার, ডাবল নয়। উপরের মন্তব্যগুলিতে একটি একক স্ল্যাশ দেখানো হওয়ায় আমি মন্তব্যটি সম্পাদনা করতে যাচ্ছি।
টিম

67

এটা চেষ্টা কর:

 sed "s/Suzi/$secondString/g" <<<"$firstString"

19
এর জন্য আপনার আসলে শেডের দরকার নেই; বাশ স্থানীয়ভাবে এই ধরণের প্রতিস্থাপনকে সমর্থন করে।
রুখ

12
আমার মনে হয় এটি "বাশ" ট্যাগ হয়েছে তবে এখানে এসেছিল কারণ অন্য শেলের জন্য কিছু সাধারণ প্রয়োজন। এটি উইকিউবুন্টু.com/… কী দরকার তা দেখে মনে হচ্ছে এটির একটি সুন্দর সংযোগ বিকল্প ।
নাতিভ

3
এটি ছাই / ড্যাশ বা অন্য কোনও পসিক্স শের জন্য দুর্দান্ত কাজ করে।
যোশুয়া ওয়ুইটস

2
আমি ত্রুটি পেয়েছি : -১ এক্সপ্রেশন # 1, চতুর্থ 9: অজানা বিকল্প
নাম জি ভিইউ

1
প্রথম উত্তর যা স্টিডিনের সাথে কাজ করে, পাইপলাইনের স্ট্রিংয়ের জন্য দুর্দান্ত।
21

46

sedস্ট্রিংগুলিতে রেজিপ্যাক্সের অক্ষর থাকলে বাশ ব্যবহার করা ভাল ।

echo ${first_string/Suzi/$second_string}

এটি উইন্ডোজে পোর্টেবল এবং কমপক্ষে পুরানো বাশ 3.1 এর সাথে কাজ করে।

আপনার পালানোর বিষয়ে খুব বেশি চিন্তা করার দরকার নেই তা দেখানোর জন্য আসুন এটি চালু করুন:

/home/name/foo/bar

এটিতে:

~/foo/bar

তবে কেবল যদি /home/nameশুরুতে থাকে। আমাদের দরকার নেই sed!

প্রদত্ত যে বাশ আমাদের যাদু ভেরিয়েবলগুলি দেয় $PWDএবং $HOMEআমরা করতে পারি:

echo "${PWD/#$HOME/\~}"

সম্পাদনা: উদ্ধৃতি / পালানোর বিষয়ে নোটের মন্তব্যে মার্ক হাফারক্যাম্পের জন্য ধন্যবাদ ~*

ভেরিয়েবলটিতে কীভাবে $HOMEস্ল্যাশ রয়েছে তা নোট করুন কিন্তু এতে কোনও কিছুই ভাঙ্গেনি।

আরও পড়ুন: অ্যাডভান্সড ব্যাশ-স্ক্রিপ্টিং গাইড
যদি ব্যবহার sedকরা আবশ্যক হয় তবে প্রতিটি চরিত্রের হাত থেকে বাঁচতে ভুলবেন না ।


এই উত্তরটি আমার ব্যবহার থেকে বন্ধ sedসঙ্গে pwdকমান্ড একটি নতুন পরিবর্তনশীল প্রতিটি সময় সংজ্ঞা আমার কাস্টম এড়াতে $PS1রান। বাশ কি স্ট্রিং প্রতিস্থাপনের জন্য কমান্ডের আউটপুট ব্যবহার করার জন্য যাদু ভেরিয়েবলের চেয়ে আরও সাধারণ উপায় সরবরাহ করে? আপনার কোড হিসাবে, আমাকে ~বাশকে $ ঘরে প্রসারিত করা থেকে বাঁচতে বাঁচতে হয়েছিল । এছাড়াও, #আপনার আদেশে কি করে?
মার্ক হাফার্ক্যাম্প 26'15

1
@MarkHaferkamp এই দেখুন থেকে "আরো পড়ার সুপারিশ" লিঙ্কটি। "পালাতে" সম্পর্কে ~: খেয়াল করুন কীভাবে আমি স্টাফ উদ্ধৃত করেছি। সর্বদা জিনিস উদ্ধৃতি মনে রাখবেন! এবং এটি কেবল যাদু ভেরিয়েবলের জন্যই কাজ করে না: কোনও ভেরিয়েবল প্রতিস্থাপনের ক্ষেত্রে স্ট্রিং দৈর্ঘ্য এবং আরও অনেক কিছু পেতে সক্ষম। আপনার $PS1দ্রুত চেষ্টা করার জন্য অভিনন্দন : আপনি $PROMPT_COMMANDযদি অন্য প্রোগ্রামিং ভাষায় আরও স্বাচ্ছন্দ্য বোধ করেন এবং একটি সংকলিত প্রম্পট কোড করতে চান তবে আপনার আগ্রহীও হতে পারে।
ক্যামিলো মার্টিন

"আরও পড়া" লিঙ্কটি "#" ব্যাখ্যা করে। 4.3.30 বাশ-এ, echo "${PWD/#$HOME/~}"আমার $HOMEসাথে প্রতিস্থাপন করবেন না ~। প্রতিস্থাপন করা হচ্ছে ~সঙ্গে \~বা '~'কাজ করে। এই 4.4.5.5 বাশ এ অন্য কোনও ডিস্ট্রোতে কোনও কাজ। ~আরও ভাল সামঞ্জস্যের জন্য আপনি উদ্ধৃতি দিতে বা এড়াতে দয়া করে আপনার পোস্টটি আপডেট করতে পারেন ? আমার "ম্যাজিক ভেরিয়েবল" প্রশ্নটি দ্বারা আমি কী বোঝাতে চাইছিলাম: আমি কি বাশের পরিবর্তনশীল বিকল্পটি ব্যবহার করতে পারি, উদাহরণস্বরূপ, unameএটিকে প্রথমে পরিবর্তনশীল হিসাবে সংরক্ষণ না করে আউটপুট ব্যবহার করতে পারি ? আমার ব্যক্তিগত হিসাবে $PROMPT_COMMAND, এটি জটিল
মার্ক হাফারক্যাম্প

@ মার্কহ্যাফের্ক্যাম্প হু, তুমি ঠিক বলেছ, আমার খারাপ। উত্তরটি এখনই আপডেট করবে।
কামিলো মার্টিন

1
@ মার্কহাফের্ক্যাম্প বাশ এবং এর অস্পষ্ট সমস্যাগুলি ...: পি
ক্যামিলো মার্টিন

19

আগামীকাল যদি আপনি সিদ্ধান্ত নেন আপনি বিবাহকে পছন্দ করেন না হয় সে পাশাপাশি প্রতিস্থাপন করা যেতে পারে:

today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt

আপনার প্রেমিককে ছেড়ে যাওয়ার 50 টি উপায় থাকতে হবে।


9

যেহেতু আমি কোনও মন্তব্য যুক্ত করতে পারি না। @ruaka উদাহরণটি আরও পঠনযোগ্য করে তুলতে এটি লিখুন

full_string="I love Suzy and Mary"
search_string="Suzy"
replace_string="Sara"
my_string=${full_string/$search_string/$replace_string}
or
my_string=${full_string/Suzy/Sarah}

আমি আপনার উদাহরণে না আসা পর্যন্ত আমি অর্ডারটি অন্য রাস্তায় বুঝতে পেরেছিলাম। এটি যা ঘটছে তা স্পষ্ট করতে সহায়তা করেছিল
raghav710

5

বিশুদ্ধ POSIX শেল পদ্ধতি, যা অসদৃশ রোমান Kazanovskyi এর sedভিত্তিক উত্তর কোন বহিরাগত সরঞ্জাম প্রয়োজন, শুধু শেল নিজস্ব নেটিভ প্যারামিটার প্রসারণও । নোট করুন যে দীর্ঘ ফাইলের নামগুলি হ্রাস করা হয়েছে তাই কোডটি একটি লাইনে আরও ভাল ফিট করে:

f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"

আউটপুট:

I love Sara and Marry

কিভাবে এটা কাজ করে:

  • ক্ষুদ্রতম প্রত্যয় প্যাটার্ন সরান। "${f%$t*}"আয় " I love" যদি প্রত্যয় $t" Suzi*" হয় $f" "। I love Suzi and Marry

  • তবে যদি t=Zelda, তবে "${f%$t*}"কিছুই মুছে না, এবং পুরো স্ট্রিং " I love Suzi and Marry" প্রদান করে।

  • এটি পরীক্ষার জন্য ব্যবহৃত হয় যা $tএর $fসাথে থাকে কিনা যদি সেই স্ট্রিংটিতে সত্যটি[ "${f%$t*}" != "$f" ] মূল্যায়ন করা হয় যদি $fস্ট্রিংটি " Suzi*" থাকে এবং মিথ্যা না থাকে।

  • যদি পরীক্ষাটি সত্য হয় , " " ছোট ছোট প্রত্যয় প্যাটার্ন সরান${f%$t*} " I love" ব্যবহার করে পছন্দসই স্ট্রিংটি তৈরি করুন এবং " " দ্বিতীয় স্ট্রিংয়ের মধ্যে " " সাথে ছোট্ট উপসর্গ প্যাটার্নটি ${f#*$t} " and Marry" সরান$sSara


5

আমি জানি এটি পুরানো তবে যেহেতু কেউ অ্যাজকি ব্যবহারের কথা উল্লেখ করেনি:

    firstString="I love Suzi and Marry"
    echo $firstString | awk '{gsub("Suzi","Sara"); print}'

1
সেই কৌশলটি হ'ল সেই পথটি যা আপনি যা ভাগ করার চেষ্টা করছেন তা আসলে কোনও চলক নয় তবে একটি টেক্সট ফাইলে। ধন্যবাদ, পেয়াম!
ফিলিপ এসএস স্নাইডার

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