উত্তর:
ব্যবহার করুন cut
সঙ্গে _
ক্ষেত্র বিভেদক হিসেবে এবং আকাঙ্ক্ষিত ক্ষেত্র পাবেন:
A="$(cut -d'_' -f2 <<<'one_two_three_four_five')"
B="$(cut -d'_' -f4 <<<'one_two_three_four_five')"
আপনি echo
এখানে স্ট্রিংয়ের পরিবর্তে পাইপ ব্যবহার করতে পারেন :
A="$(echo 'one_two_three_four_five' | cut -d'_' -f2)"
B="$(echo 'one_two_three_four_five' | cut -d'_' -f4)"
উদাহরণ:
$ s='one_two_three_four_five'
$ A="$(cut -d'_' -f2 <<<"$s")"
$ echo "$A"
two
$ B="$(cut -d'_' -f4 <<<"$s")"
$ echo "$B"
four
$ echo $FILE
my_user/my_folder/file.csv
$ A="$(cut -d'/' -f2 <<<"$FILE")"
$ echo $A
[file]*
আপনি কি জানেন এখানে কী হচ্ছে?
echo "${s##*_}"
কেবল POSIX sh কনস্ট্রাক্টস ব্যবহার করে, আপনি একবারে একটি ডিলিমিটার পার্স করতে প্যারামিটার সাবস্টিটিউশন কনস্ট্রাক্টস ব্যবহার করতে পারেন । নোট করুন যে এই কোডটি ধরে নিয়েছে যে প্রয়োজনীয় ক্ষেত্রগুলির সংখ্যা রয়েছে, অন্যথায় শেষ ক্ষেত্রটি পুনরাবৃত্তি হয়।
string='one_two_three_four_five'
remainder="$string"
first="${remainder%%_*}"; remainder="${remainder#*_}"
second="${remainder%%_*}"; remainder="${remainder#*_}"
third="${remainder%%_*}"; remainder="${remainder#*_}"
fourth="${remainder%%_*}"; remainder="${remainder#*_}"
বিকল্পভাবে, আপনি ওয়াইল্ডকার্ড সম্প্রসারণ অক্ষম করে এবং IFS
ডিলিমিটার চরিত্রের সাথে সেট করে একটি অব্যক্ত প্যারামিটার বিকল্প ব্যবহার করতে পারেন (ডিলিমিটারটি যদি একক অ-হোয়াইটস্পেস অক্ষর হয় বা কোনও হোয়াইটস্পেস সিকোয়েন্সটি একটি ডিলিমিটার হয় তবে এটি কেবল কাজ করে)।
string='one_two_three_four_five'
set -f; IFS='_'
set -- $string
second=$2; fourth=$4
set +f; unset IFS
এই ক্লোবারগুলি অবস্থানগত পরামিতি। আপনি যদি কোনও ফাংশনে এটি করেন তবে কেবলমাত্র ফাংশনের অবস্থানগত পরামিতিগুলি প্রভাবিত হবে।
তবুও আরেকটি পদ্ধতি হ'ল read
বিল্টিন ব্যবহার করা use
IFS=_ read -r first second third fourth trail <<'EOF'
one_two_three_four_five
EOF
unset IFS
ফিরে না IFS
। এর পরে যদি কারও কারও OldIFS="$IFS"
ওল্ডআইএফএসের নালিকাগুলি থাকে। এছাড়াও, এটি ধরে নেওয়া হচ্ছে যে আইএফএসের পূর্বের মানটি ডিফল্ট, যা না হওয়া খুব সম্ভব (এবং দরকারী)। কেবলমাত্র সঠিক সমাধান হ'ল old="$IFS"
আইএফএস = "$ পুরানো" দিয়ে সঞ্চয় করা এবং পরে পুনরুদ্ধার করা। বা ... একটি সাব-শেল ব্যবহার করুন (...)
। বা, আরও ভাল, আমার উত্তর পড়ুন।
unset IFS
পুনরুদ্ধার করে না IFS
, তবে এটি ক্ষেত্র বিভাজনকে ডিফল্ট প্রভাবকে ফিরিয়ে দেয়। হ্যাঁ, এটি একটি সীমাবদ্ধতা, তবে সাধারণত অনুশীলনে এটি একটি গ্রহণযোগ্য। সাব-শেলের সমস্যাটি হ'ল আমাদের এটি থেকে ডেটা বের করা দরকার। আমি এমন একটি সমাধান দেখাব যা শেষ পর্যন্ত রাষ্ট্র পরিবর্তন করে না read
। (এটি পসিএক্স শেলগুলিতে কাজ করে, তবে বোর্ন শেলটিতে আইআইআরসি নয় কারণ এটি read
এখানে-নথির কারণে সাবসেলে চালানো হবে )) <<<
আপনার উত্তর হিসাবে ব্যবহার করা একটি বৈকল্পিক যা কেবল ksh / bash / zsh এ কাজ করে।
user/my_folder/[this_is_my_file]*
? আমি কি প্রাপ্ত যখন আমি এই পদক্ষেপগুলি অনুসরণ করুন হল[this_is_my_file]*
/
।
একটি awk
উত্তর দেখতে চেয়েছিলেন , সুতরাং এখানে একটি:
A=$(awk -F_ '{print $2}' <<< 'one_two_three_four_five')
B=$(awk -F_ '{print $4}' <<< 'one_two_three_four_five')
awk -F_ '{print $NF}' <<< 'one_two_3_4_five'
সবচেয়ে সহজ উপায় (<<< সহ শাঁসের জন্য) হ'ল:
IFS='_' read -r a second a fourth a <<<"$string"
$a
পরিবর্তে একটি টেম্পোরাল ভেরিয়েবল ব্যবহার করা হচ্ছে $_
কারণ একটি শেল অভিযোগ করে।
একটি পূর্ণ স্ক্রিপ্টে:
string='one_two_three_four_five'
IFS='_' read -r a second a fourth a <<<"$string"
echo "$second $fourth"
কোনও আইএফএস পরিবর্তন হচ্ছে না, set -f
(পথের নাম সম্প্রসারণ) নিয়ে ইস্যু নয়, অবস্থানগত পরামিতিগুলিতে কোনও পরিবর্তন নেই ("$ @")।
আইএফএস পরিবর্তন না করে সমস্ত শেলের (হ্যাঁ, সমস্ত পসিক্স অন্তর্ভুক্ত) পোর্টেবল সমাধানের জন্য বা set -f
(কিছুটা জটিল) হেরিডোক সমতুল্য ব্যবহার করুন:
string='one_two_three_four_five'
IFS='_' read -r a second a fourth a <<-_EOF_
$string
_EOF_
echo "$second $fourth"
বুঝতে হবে যে এই সমাধানগুলি (এখানে-ডক এবং এর ব্যবহার উভয়ই <<<
সব পেছনের নতুন লাইনগুলি সরিয়ে ফেলবে
And এবং এটি একটি "এক লাইনার" ভেরিয়েবল কনটেন্টের জন্য ডিজাইন করা হয়েছে
multi মাল্টি-লাইনারগুলির জন্য সমাধানগুলি সম্ভব তবে আরও জটিল কাঠামোগত প্রয়োজন।
ব্যাশ সংস্করণ ৪.৪-তে একটি খুব সহজ সমাধান সম্ভব
readarray -d _ -t arr <<<"$string"
echo "array ${arr[1]} ${arr[3]}" # array numbers are zero based.
অনেকগুলি পসিক্স শেলের জন্য অ্যারে না থাকায় পসিএক্স শেলগুলির সমতুল্য নেই।
অ্যারে রয়েছে এমন শেলগুলির জন্য এটি
এতটা সহজ হতে পারে: (আতশ, লক্ষ, মক্ষ, কেএসএইচ, এবং বাশে কাজ করার জন্য পরীক্ষিত)
set -f; IFS=_; arr=($string)
তবে ভেরিয়েবল এবং বিকল্পগুলি রাখতে এবং পুনরায় সেট করতে প্রচুর অতিরিক্ত নদীর গভীরতানির্ণয় সহ:
string='one_* *_three_four_five'
case $- in
*f*) noglobset=true; ;;
*) noglobset=false;;
esac
oldIFS="$IFS"
set -f; IFS=_; arr=($string)
if $noglobset; then set -f; else set +f; fi
echo "two=${arr[1]} four=${arr[3]}"
Zsh এ, অ্যারেগুলি 1 এ শুরু হয় এবং ডিফল্টভাবে স্ট্রিং বিভক্ত হয় না।
সুতরাং zsh এ কাজ করার জন্য কিছু পরিবর্তন করা দরকার।
read
যতক্ষণ ব্যবহার করা যায় ততক্ষণ সহজ হয় যতক্ষণ না ওপি একটি দীর্ঘ স্ট্রিং থেকে 76 তম এবং 127 তম উপাদানগুলি বের করতে চায় না ...
readarray
এই পরিস্থিতির জন্য ব্যবহার করা সহজতর হতে পারে।
zsh
আপনি স্ট্রিং (অন _
) একটি অ্যারে মধ্যে বিভক্ত করতে পারে সঙ্গে :
elements=(${(s:_:)string})
এবং তারপরে অ্যারে ইনডেক্সের মাধ্যমে প্রতিটি / যে কোনও উপাদান অ্যাক্সেস করুন:
print -r ${elements[4]}
মনে রাখবেন যে মধ্যে zsh
(অসদৃশ ksh
/ bash
) অ্যারে সূচকের 1 এ শুরু ।
set -f
প্রথম সমাধানটিতে সতর্কতা যুক্ত মনে রাখবেন । ... তারকাচিহ্ন *
সম্ভবত?
set -f
? আমি read
/ ব্যবহার করছি না IFS
। আমার সমাধানগুলি যেমন *_*_*
বা যাই হোক না কেন স্ট্রিং দিয়ে চেষ্টা করুন ...
আর একটি উদার উদাহরণ; বুঝতে সহজ।
A=\`echo one_two_three_four_five | awk -F_ '{print $1}'\`
B=\`echo one_two_three_four_five | awk -F_ '{print $2}'\`
C=\`echo one_two_three_four_five | awk -F_ '{print $3}'\`
... and so on...
ভেরিয়েবলের সাথেও ব্যবহার করা যেতে পারে।
মনে করুন:
এটি_যাত্রা = "এক_দুই_ তিনটি_চয়দা_ফাইভ"
তারপরে নিম্নলিখিতগুলি কাজ করে:
এ = cho প্রতিধ্বনি $ {this_str} | awk -F_ '{মুদ্রণ $ 1}' `
বি =` প্রতিধ্বনি $ {this_str} | awk -F_ '{মুদ্রণ $ 2}' `
সি =` প্রতিধ্বনি $ {this_str} | awk -F_ '{মুদ্রণ $ 3}' `
... এবং আরও ...