কমা দ্বারা পৃথক শেল ভেরিয়েবলের মধ্য দিয়ে লুপ করুন


114

মনে করুন নীচের মতো আমার কাছে ইউনিক্স শেল ভেরিয়েবল রয়েছে

variable=abc,def,ghij

আমি সব মান (বের করে আনতে চান abc, defএবং ghij) লুপ জন্য একটি ব্যবহার করে এবং একটি পদ্ধতি মধ্যে প্রতিটি মান পাস।

স্ক্রিপ্টটি থেকে কমা-বিভাজিত মানগুলির স্বেচ্ছাসেবী সংখ্যা বের করার অনুমতি দেওয়া উচিত $variable


পুনরাবৃত্তি করে আপনি ঠিক কী করতে চান?
এসএমএ

4
আমি পদ্ধতির আর্গুমেন্ট হিসাবে প্রতিটি ক্ষেত্রকে (আব্বাস বলি) পাস করতে চাই।
রামানাথন কে

উত্তর:


138

আপনি কেবলমাত্র কমা দ্বারা পৃথক হওয়া যতক্ষণ না তার কতগুলি ক্ষেত্র রয়েছে তা বিবেচনা করে আপনার চলকটির মাধ্যমে গতিশীলভাবে অতিক্রম করতে আপনি নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করতে পারেন।

variable=abc,def,ghij
for i in $(echo $variable | sed "s/,/ /g")
do
    # call your procedure/other scripts here below
    echo "$i"
done

echo "$i"উপরের কলটির পরিবর্তে , লুপটির জন্য doএবং doneঅভ্যন্তরের মধ্যে, আপনি আপনার পদ্ধতিটি শুরু করতে পারেন proc "$i"


আপডেট : উপরের স্নিপেটটি যদি ভেরিয়েবলের মান ফাঁক না করে কাজ করে। আপনার যদি এরকম প্রয়োজন হয় তবে দয়া করে যে কোনও সমাধান পরিবর্তন করতে পারেন IFSএবং তারপরে আপনার পরিবর্তনশীলটিকে পার্স করতে পারেন ।


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


10
এই কাজ করে না যদি $variable, সাদা ব্যবধান সমন্বিত উদাঃ variable=a b,c,d=> প্রিন্ট 4 লাইন (ক | খ | গ | ঘ) বদলে 3 (AB | গ | ঘ)
ড্যান

পাশাপাশি এটি ** "value ** এর মতো নতুন উদ্ধৃতি যুক্ত হচ্ছে । সেই অপসারণের জন্য যদি কোনও
রেইগেক্স

144

আইএফএসের সাথে গোলযোগ
না করা বাহ্যিক কমান্ড কল করছে না calling

variable=abc,def,ghij
for i in ${variable//,/ }
do
    # call your procedure/other scripts here below
    echo "$i"
done

ব্যাশ স্ট্রিং ম্যানিপুলেশন ব্যবহার করে http://www.tldp.org/LDP/abs/html/string-manipulation.html


4
এটি সম্পর্কে দুর্দান্ত জিনিস হ'ল আপনি বিভিন্ন ডেলিফিটার ব্যবহার করে একাধিক লুপকে বাসাতে পারেন। ভাল পরামর্শ!
ব্র্যাড পার্কস

6
গণ্ডগোল এড়ানোর জন্য দুর্দান্ত টিপ IFS!
লাইমনসিজাস

16
ছোট সতর্কতা - যদি মানগুলির মধ্যে কোনও $iশূন্যস্থান থাকে তবে সেগুলি বিভক্ত হয়ে যাবে (এবং এ কারণেই এটি স্থান-বিচ্ছিন্নের পরিবর্তে কমা-বিচ্ছিন্ন হিসাবে উত্তীর্ণ হতে পারে)
টবি স্পাইট

4
যদি পূর্ববর্তী কোনও ফাংশন আইএফএস সেটিংস পরিবর্তন করে, তবে এটি কাজ করে না ... এটিতে এটি পরিবর্তন করুন:for i in ${variable//,/$IFS} do; echo "$i"; done
জোপ

4
আমি এই পদ্ধতির চেষ্টা করার পরে আমি ত্রুটি বার্তাটি "খারাপ প্রতিস্থাপন" পাই।
ক্রোটচেট

56

আপনি যদি কোনও পৃথক ক্ষেত্র বিভাজক সেট করেন, আপনি সরাসরি একটি forলুপ ব্যবহার করতে পারেন :

IFS=","
for v in $variable
do
   # things with "$v" ...
done

আপনি মানগুলিকে একটি অ্যারেতেও সংরক্ষণ করতে পারেন এবং তারপরে লুপটি বাশতে একটি ডিলিমিটারে কীভাবে একটি স্ট্রিং বিভক্ত করতে পারি তাতে নির্দেশিত হয়েছে ? :

IFS=, read -ra values <<< "$variable"
for v in "${values[@]}"
do
   # things with "$v"
done

পরীক্ষা

$ variable="abc,def,ghij"
$ IFS=","
$ for v in $variable
> do
> echo "var is $v"
> done
var is abc
var is def
var is ghij

কমা-বিচ্ছিন্ন তালিকার মাধ্যমে পুনরাবৃত্তি করতে এবং প্রতিটি প্রবেশের জন্য একটি আদেশ কার্যকর করতে এই সমাধানে আপনি একটি বিস্তৃত পদ্ধতির সন্ধান করতে পারেন ।

দ্বিতীয় পদ্ধতির উদাহরণ:

$ IFS=, read -ra vals <<< "abc,def,ghij"
$ printf "%s\n" "${vals[@]}"
abc
def
ghij
$ for v in "${vals[@]}"; do echo "$v --"; done
abc --
def --
ghij --

এছাড়াও স্ট্যাকওভারফ্লো.com/ জিজ্ঞাসা / 918886/… :-) দেখুন সকলের জন্য শুভকামনা।
শেলটার

হ্যাঁ! আমি সে সম্পর্কেও ভেবেছিলাম, কেবল তারপরেই পদক্ষেপগুলি প্রয়োজন: একটি whileঅ্যারেতে পড়তে হবে এবং ফলাফলের মধ্য দিয়ে লুপ করতে হবে অন্যটি।
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন

4
আমাকে খুশী করে তোলে যখন কেউ বাস্তবে শেলটি কীভাবে ব্যবহার করতে হয় তার পরিবর্তে একগুচ্ছ বিনুটি পাইপ না করে use
পিটারটি

আপনি কি IFSআগে যা ছিল তা ফিরিয়ে দিতে হবে?
pstanton

4
@ ফেডরকিই এটা করেছে! এটিই কেবলমাত্র পরিবর্তনশীল যা আমি লুপ করতে চেয়েছিলাম এবং এটি আমার ইয়ামল ফাইলটি পড়া সহজ করে দিয়েছে (এক দীর্ঘ পরিবেশের পরিবর্তের পরিবর্তে এটিতে একগুচ্ছ সারি রয়েছে)
গ্যামা গেমস

6
#/bin/bash   
TESTSTR="abc,def,ghij"

for i in $(echo $TESTSTR | tr ',' '\n')
do
echo $i
done

আমি শেডের পরিবর্তে টিআর ব্যবহার করতে পছন্দ করি, কিছু ক্ষেত্রে ক্ষেত্রে ouse r \ n এর মতো বিশেষ অক্ষরগুলির সাথে বেকোস সেডের সমস্যা আছে।

অন্যান্য সমাধান হ'ল নির্দিষ্ট বিভাজককে আইএফএস সেট করা


1

এখানে একটি বিকল্প টিআর ভিত্তিক সমাধান যা প্রতিধ্বনি ব্যবহার করে না, ওয়ান-লাইনার হিসাবে প্রকাশিত।

for v in $(tr ',' '\n' <<< "$var") ; do something_with "$v" ; done

এটি প্রতিধ্বনি ব্যতীত পরিপাটি বোধ করে তবে এটি কেবল আমার ব্যক্তিগত পছন্দ।


0

আর একবার চেষ্টা কর.

#/bin/bash   
testpid="abc,def,ghij" 
count=`echo $testpid | grep -o ',' | wc -l` # this is not a good way
count=`expr $count + 1` 
while [ $count -gt 0 ]  ; do
     echo $testpid | cut -d ',' -f $i
     count=`expr $count - 1 `
done

তবে আমি যদি ভেরিয়েবল টেস্টপিডে ক্ষেত্রের সংখ্যা সম্পর্কে নিশ্চিত না হই তবে কী হবে?
রামানাথন কে

এছাড়াও, আমাকে উপরের ভেরিয়েবলের প্রতিটি ফাইল করা একটি পদ্ধতির যুক্তি হিসাবে পাস করতে হবে। এবং আমি ভেরিয়েবলের দৈর্ঘ্য শূন্য না হওয়া পর্যন্ত এটি করতে চাই। (যেমন; সমস্ত ক্ষেত্রগুলি একবার প্রক্রিয়াজাতকরণের পদ্ধতিতে পাস করা উচিত)
রমনাথন কে

আমি পদ্ধতি সম্পর্কে জানি না। এই লিঙ্ক থেকে আপনি ক্ষেত্রের গণনা পেতে পারেন। http://stackoverflow.com/questions/8629330/unix-count-of-columns-in-file। এর পরে লুপের জন্য লুপের জন্য এটি তৈরি করুন। আপনি এটি পেতে পারেন।
কার্তিকেইকন.আরএস

এটি আমার অনুমানের একটি ফাইল থেকে ক্ষেত্রগুলি গণনা করা। আমার যদি ভেরিয়েবলের ক্ষেত্রগুলি গণনা করার দরকার হয় তবে (ধরুন ভেরিয়েবলটি টেস্টপিড = এবিসি, ডিএফ, গিজ)
রামানাথন কে

ভেরিয়েবলটি প্রতিধ্বনিত করুন এবং আউটপুটটিকে অর্কের কাছে পাইপ করুন। নাহলে আমার আপডেট হওয়া উত্তরটি দেখুন। এটি দরকারী হতে পারে।
কার্তিকেইকন.আরএস

0

আইএফএস ব্যবহার না করে এবং স্পেসগুলি সংরক্ষণ করে রাখার জন্য আরও একটি সমাধান:

$ var="a bc,def,ghij"
$ while read line; do echo line="$line"; done < <(echo "$var" | tr ',' '\n')
line=a bc
line=def
line=ghij

এটি ব্যাশে সঠিকভাবে কাজ করে, তবে zsh স্পেসগুলি গ্রাস করে।
lleaff

0

এখানে আমার খাঁটি বাশের সমাধান যা আইএফএস পরিবর্তন করে না এবং এটি একটি কাস্টম রেজেক্স ডিলিমিটার নিতে পারে।

loop_custom_delimited() {
    local list=$1
    local delimiter=$2
    local item
    if [[ $delimiter != ' ' ]]; then
        list=$(echo $list | sed 's/ /'`echo -e "\010"`'/g' | sed -E "s/$delimiter/ /g")
    fi
    for item in $list; do
        item=$(echo $item | sed 's/'`echo -e "\010"`'/ /g')
        echo "$item"
    done
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.