বাশের কোনও স্ট্রিং থেকে একটি নির্দিষ্ট উপসর্গ / প্রত্যয় সরান


484

আমার bashস্ক্রিপ্টে আমার একটি স্ট্রিং এবং এর উপসর্গ / প্রত্যয় রয়েছে। মূল স্ট্রিং থেকে আমার উপসর্গ / প্রত্যয়টি সরিয়ে ফেলতে হবে।

উদাহরণস্বরূপ, আসুন বলি যে আমার নীচের মানগুলি রয়েছে:

string="hello-world"
prefix="hell"
suffix="ld"

আমি কীভাবে নিম্নলিখিত ফলাফল পেতে পারি?

result="o-wor"


14
তথাকথিত অ্যাডভান্সড বাশ স্ক্রিপ্টিং গাইডের সাথে সংযোগ করার সময় খুব সতর্ক থাকুন; এটিতে ভাল পরামর্শ এবং ভয়ঙ্কর মিশ্রণ রয়েছে।
ট্রিপল

উত্তর:


717
$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor

40
এছাড়াও ## এবং %% রয়েছে, যা as উপসর্গ বা $ প্রত্যয়টিতে ওয়াইল্ডকার্ড থাকলে যতটা সম্ভব সরিয়ে দেয়।
pts

27
দুটোকে এক লাইনে একত্রিত করার উপায় কি আছে? আমি চেষ্টা করেছি ${${string#prefix}%suffix}কিন্তু কাজ করে না।
স্থিতিশীল_আর্টিটি

28
@static_rtti না, দুর্ভাগ্যক্রমে আপনি এর মতো প্যারামিটার বিকল্পটি বাসাতে পারবেন না। আমি জানি, এটা লজ্জাজনক।
অ্যাড্রিয়ান ফ্রাওয়ার্থিথ

87
@ AdrianFrühwirth: পুরো ভাষা লজ্জার, কিন্তু এটা যাতে দরকারী :)
static_rtti

8
এনভিএম, গুগলে "বাশ সাবস্টিটিউশন" পেয়েছিল যা আমি চাইছিলাম।
টাইলার

89

সেড ব্যবহার:

$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

সেড কমান্ডের মধ্যেই, ^অক্ষরটি শুরু হওয়া পাঠ্যের সাথে মেলে $prefixএবং $শেষের পাঠ্যটি শেষ হয় $suffix

অ্যাড্রিয়ান ফ্রেহার্থে নীচের মন্তব্যে কিছু ভাল পয়েন্ট তৈরি sedকরেছে তবে এই উদ্দেশ্যে খুব কার্যকর হতে পারে। Sed উপসর্গ এবং $ প্রত্যয়ের বিষয়বস্তুগুলি সেড দ্বারা ব্যাখ্যা করা হয় তা ভাল বা খারাপ হতে পারে - যতক্ষণ আপনি মনোযোগ দিন, আপনার ঠিক হওয়া উচিত। সৌন্দর্যটি হ'ল, আপনি এরকম কিছু করতে পারেন:

$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

যা আপনি যা চান তা হতে পারে এবং এটি উভয় কল্পিত এবং ব্যাশ ভেরিয়েবল বিকল্পের চেয়ে শক্তিশালী। যদি আপনি মনে রাখেন যে দুর্দান্ত শক্তির সাথে মহান দায়িত্ব আসে (যেমন স্পাইডারম্যান বলেছেন), আপনার ভাল হওয়া উচিত।

সেডের সাথে একটি দ্রুত পরিচিতি পাওয়া যাবে http://evc-cit.info/cit052/sed_tutorial.html এ

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

প্রদত্ত বিশেষ উদাহরণের জন্য, নিম্নলিখিতগুলিও কাজ করবে:

$ echo $string | sed -e s/^$prefix// -e s/$suffix$//

... তবে কেবল কারণ:

  1. প্রতিধ্বনিটি তার তর্ক তালিকায় কতগুলি স্ট্রিং রয়েছে তা যত্ন করে না এবং
  2. $ উপসর্গ এবং $ প্রত্যয়টিতে কোনও স্থান নেই

কমান্ড লাইনের একটি স্ট্রিং উদ্ধৃত করা ভাল অভ্যাস কারণ এটিতে স্পেস থাকলেও এটি একক যুক্তি হিসাবে কমান্ডের কাছে উপস্থাপিত হবে। আমরা একই কারণে $ উপসর্গ এবং $ প্রত্যয়টি উদ্ধৃত করেছি: সিডে প্রতিটি সম্পাদনা কমান্ড একটি স্ট্রিং হিসাবে পাস করা হবে। আমরা ডাবল উদ্ধৃতি ব্যবহার করি কারণ তারা পরিবর্তনশীল অন্তরঙ্গকরণের অনুমতি দেয়; যদি আমরা সিড কমান্ডটি সিড কমান্ডটি ব্যবহার করতাম তবে এটি আক্ষরিক হয়ে উঠত $prefixএবং $suffixযা আমরা চাই তা নয়।

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


8
দুর্ভাগ্যক্রমে, এটি বেশ কয়েকটি কারণে খারাপ পরামর্শ: 1) অব্যক্ত, $stringশব্দের বিভাজন এবং গ্লোববিংয়ের সাথে সম্পর্কিত। 2) $prefixএবং $suffixএমন sedব্যাখ্যা প্রকাশ করতে পারে যা ব্যাখ্যা করবে, যেমন নিয়মিত অভিব্যক্তি বা ডিলিমিটার হিসাবে ব্যবহৃত চরিত্র যা পুরো কমান্ডটি ভেঙে দেবে। 3) sedদুই বার কল করা প্রয়োজন হয় না ( -e 's///' -e '///'পরিবর্তে আপনি পারেন ) এবং পাইপও এড়ানো যেতে পারে। উদাহরণস্বরূপ, বিবেচনা string='./ *'এবং / অথবা prefix='./'তা ভয়ঙ্করভাবে কারণে বিরতি দেখতে 1)এবং 2)
অ্যাড্রিয়ান ফ্রাথর্থম

মজাদার নোট: সিড একটি ডিলিমিটার হিসাবে প্রায় কোনও কিছু নিতে পারে। আমার ক্ষেত্রে, যেহেতু আমি পথের বাইরে উপসর্গ-ডিরেক্টরিগুলি পার্স করছিলাম /, তাই আমি ব্যবহার করতে পারিনি sed "s#^$prefix##, পরিবর্তে আমি ব্যবহার করেছি used (ফ্রেসিবিলিটি: ফাইলের নাম থাকতে পারে না #Since যেহেতু আমি ফাইলগুলি নিয়ন্ত্রণ করি তাই আমরা সেখানে নিরাপদ থাকি))
অলি

@ অলি ফাইলনামগুলিতে স্ল্যাশ এবং নাল অক্ষর ব্যতীত অন্য কোনও অক্ষর থাকতে পারে তাই আপনি নিয়ন্ত্রণে না থাকলে আপনি কোনও ফাইলের নাম নির্দিষ্ট অক্ষর না ধারণ করে ধরে নিতে পারবেন না।
অ্যাড্রিয়ান ফ্রেহওয়ার্থ

হ্যাঁ, আমি সেখানে কী ভাবছিলাম তা জানেন না। আইওএস হতে পারে? জানিনা। ফাইলের নামগুলিতে অবশ্যই "#" থাকতে পারে। আমি কেন বললাম ধারণা নেই। :)
অলি

@ অলি: আমি যেমন আপনার মূল মন্তব্যটি বুঝতে পেরেছিলাম, আপনি বলছিলেন যে সেডের #ডিলিমিটার হিসাবে আপনার পছন্দকে সীমাবদ্ধ করার অর্থ আপনি সেই অক্ষরযুক্ত ফাইলগুলি পরিচালনা করতে পারবেন না।
পি ড্যাডি

17

আপনি কি আপনার উপসর্গ এবং প্রত্যয়টির দৈর্ঘ্য জানেন? আপনার ক্ষেত্রে:

result=$(echo $string | cut -c5- | rev | cut -c3- | rev)

বা আরও সাধারণ:

result=$(echo $string | cut -c$((${#prefix}+1))- | rev | cut -c$((${#suffix}+1))- | rev)

তবে অ্যাড্রিয়ান ফ্রাহ্বারথের সমাধানটি দুর্দান্ত cool আমি সে সম্পর্কে জানতাম না!


14

আমি পাথ থেকে উপসর্গগুলি সরাতে গ্রেপ ব্যবহার করি (যা ভালভাবে পরিচালনা করা হয় না sed):

echo "$input" | grep -oP "^$prefix\K.*"

\K এর আগে সমস্ত অক্ষর ম্যাচ থেকে সরিয়ে দেয়।


grep -Pএটি একটি মানহীন এক্সটেনশন। আপনার প্ল্যাটফর্মে এটি সমর্থন করা থাকলে আপনার কাছে আরও শক্তি, তবে আপনার কোডটি যথাযথভাবে পোর্টেবল করার প্রয়োজন হলে এটি সন্দেহজনক পরামর্শ।
ট্রিপলি

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

1
না, ম্যাকওএসের উদাহরণস্বরূপ ব্যাশটি বাক্সের বাইরে রয়েছে তবে জিএনইউ নয় grep। পূর্ববর্তী সংস্করণগুলিতে আসলে -Pবিএসডি থেকে বিকল্প ছিল grepতবে তারা এটি সরিয়ে ফেলে।
ট্রিপলি

9
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"

$ #remove "hell" from "hello-world" if "hell" is found at the beginning.
$ prefix_removed_string=${string/#$prefix}

$ #remove "ld" from "o-world" if "ld" is found at the end.
$ suffix_removed_String=${prefix_removed_string/%$suffix}
$ echo $suffix_removed_String
o-wor

মন্তব্য:

# $ উপসর্গ: যোগ করা # নিশ্চিত করে যে "নরকে" স্ট্রিংিং কেবলমাত্র শুরুতে পাওয়া গেলে সরিয়ে দেওয়া হবে। % $ প্রত্যয়:% যোগ করা নিশ্চিত করে যে "এলডি" স্ট্রিংগুলি কেবলমাত্র শেষের দিকে পাওয়া গেলে সরিয়ে দেওয়া হবে।

এগুলি ব্যতীত, "নরক" এবং "এলডি" সাবস্ট্রিংগুলি সর্বত্র সরিয়ে ফেলা হবে, এমনকি এটি মাঝখানে পাওয়া যাবে।


নোটস জন্য ধন্যবাদ! কিউকিউ: আপনার কোড উদাহরণে আপনারও /স্ট্রিংয়ের ঠিক পরে একটি ফরোয়ার্ড স্ল্যাশ রয়েছে , এটি কিসের জন্য?
ডিয়েগোসালাজার

1
/ বর্তমান স্ট্রিং এবং সাব স্ট্রিং পৃথক করে। উপ-স্ট্রিং এখানে পোস্ট করা প্রশ্নের প্রত্যয়।
বিজয় ভ্যাট


6

ছোট এবং সর্বজনীন সমাধান:

expr "$string" : "$prefix\(.*\)$suffix"

1
আপনি যদি ব্যাশ ব্যবহার করছেন তবে আপনার সম্ভবত সম্ভবত ব্যবহার exprকরা উচিত নয়। মূল বোর্ন শেলের দিনগুলিতে এটি ছিল এক প্রকারের সুবিধাজনক রান্নাঘর সিঙ্ক ইউটিলিটি, তবে এখন এটি তার সেরা-পূর্বের তারিখটি পেরিয়ে গেছে।
ট্রিপলি

5

@ অ্যাড্রিয়ান ফ্রাহ্বারথ উত্তরটি ব্যবহার করে:

function strip {
    local STRING=${1#$"$2"}
    echo ${STRING%$"$2"}
}

এটি এটি ব্যবহার করুন

HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello

0

আমি রেজিজেসে ক্যাপচার গ্রুপগুলি ব্যবহার করব:

$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ set +H # Disables history substitution, can be omitted in scripts.
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/" <<< $string
o-wor
$ string1=$string$string
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/g" <<< $string1
o-woro-wor

((?:(?!(${suffix})).)*)নিশ্চিত করে তোলে যে কন্টেন্ট ${suffix}ক্যাপচার গ্রুপ থেকে বাদ দেওয়া হবে। উদাহরণস্বরূপ, এটি স্ট্রিং এর সমতুল্য [^A-Z]*। অন্যথায় আপনি পাবেন:

$ perl -pe "s/${prefix}(.*)${suffix}/\1/g" <<< $string1
o-worldhello-wor
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.