ব্যাশে টিপলস থেকে লুপ করা কি সম্ভব?
উদাহরণ হিসাবে, নিম্নলিখিতটি যদি কাজ করে তবে তা দুর্দান্ত হবে:
for (i,j) in ((c,3), (e,5)); do echo "$i and $j"; done
এমন কোনও কর্মপরীক্ষা রয়েছে যা আমাকে কোনওভাবে টিপলস থেকে লুপ করতে দেয়?
ব্যাশে টিপলস থেকে লুপ করা কি সম্ভব?
উদাহরণ হিসাবে, নিম্নলিখিতটি যদি কাজ করে তবে তা দুর্দান্ত হবে:
for (i,j) in ((c,3), (e,5)); do echo "$i and $j"; done
এমন কোনও কর্মপরীক্ষা রয়েছে যা আমাকে কোনওভাবে টিপলস থেকে লুপ করতে দেয়?
উত্তর:
$ for i in c,3 e,5; do IFS=","; set -- $i; echo $1 and $2; done
c and 3
e and 5
set
(থেকে man builtins
) এর এই ব্যবহার সম্পর্কে :
বিকল্প প্রক্রিয়াজাতকরণের পরে থাকা যে কোনও আর্গুমেন্টকে অবস্থানগত পরামিতিগুলির মান হিসাবে বিবেচনা করা হয় এবং ক্রমে $ 1, $ 2, ... $ n এ নির্ধারিত হয়
IFS=","
ক্ষেত্র বিভাজক তাই সেট করে $i
মধ্যে ভাগ পরার $1
এবং $2
সঠিকভাবে।
এই ব্লগ মাধ্যমে ।
সম্পাদনা করুন: আরও সঠিক সংস্করণ, @ স্ল্যাকডিয়ামামন্ডের পরামর্শ অনুসারে:
$ OLDIFS=$IFS; IFS=','; for i in c,3 e,5; do set -- $i; echo $1 and $2; done; IFS=$OLDIFS
c and 3
e and 5
IFS
সংরক্ষণ করা উচিত এবং যদি এটি কমান্ড লাইনে চালিত হয় তবে তার মূল মানটিতে পুনরায় সেট করা উচিত। এছাড়াও, IFS
প্রতিটি পুনরাবৃত্তির পরিবর্তে লুপটি চালানোর আগে নতুনটি একবার সেট করা যায়।
set -- $i
IFS
, শুধুমাত্র এটি সেট set
কমান্ড প্রয়োগ করুন: for i in c,3 e,5; do IFS="," set -- $i; echo $1 and $2; done
। দয়া করে আপনার উত্তরটি সম্পাদনা করুন: সমস্ত পাঠক যদি তালিকাবদ্ধ সমাধানগুলির মধ্যে একটি মাত্র চয়ন করেন তবে সম্পূর্ণ বিকাশের ইতিহাস পড়ার কোনও ধারণা নেই। এই দুর্দান্ত কৌশলটির জন্য ধন্যবাদ!
tuples="a,1 b,2 c,3"
এবং রাখিIFS=','
c,3 e,5
ব্যবহারের$tuples
এটি মোটে ভাল মুদ্রণ করে না। তবে এর পরিবর্তে যদি আমি লুপের জন্য কীওয়ার্ডের IFS=','
পরে রাখি তবে লিটারেরাল মানগুলি do
ব্যবহার করার সময় এটি ভাল কাজ করে $tuples
। শুধু ভেবেছি এটি বলার অপেক্ষা রাখে না।
IFS
পুনরাবৃত্তিগুলি বিভক্ত করতে ব্যবহার করে। অর্থাত্ যদি আপনি কোনও অ্যারের উপরে লুপ করেন arr=("c,3" "e,5")
এবং রাখেনIFS
তবে এর মান $i
ঠিক হবে c
এবং e
, এটি বিভক্ত হয়ে যাবে 3
এবং 5
তাই set
সঠিকভাবে বিশ্লেষণ $i
করবে না কারণ পার্স করার মতো কিছু থাকবে না। এর অর্থ হ'ল পুনরাবৃত্তি করার মানগুলি যদি ইনলাইন করা না যায় তবে লুপটির IFS
ভিতরে রাখা উচিত এবং বাইরের মানটি পরিবর্তনশীলটির পুনরাবৃত্তির জন্য উদ্দেশ্যে বিভাজককে সম্মান করে। $tuples
এটির ক্ষেত্রে এটি সাধারণভাবে হওয়া উচিত IFS=
যা ডিফল্ট এবং সাদা স্থানের উপরে বিভক্ত হয়।
আমি বিশ্বাস করি যে এই সমাধানটি জমা দেওয়া অন্যদের চেয়ে কিছুটা ক্লিনার, এই ব্যাশ শৈলীর নির্দেশিকায় h / t কীভাবে পাঠ্যকে একটি ডিলিমিটারে স্ট্রিংগুলি বিভক্ত করতে এবং পৃথক ভেরিয়েবলগুলিতে নির্ধারণের জন্য ব্যবহার করা যেতে পারে তা বোঝানোর জন্য b
for i in c,3 e,5; do
IFS=',' read item1 item2 <<< "${i}"
echo "${item1}" and "${item2}"
done
@ এডুয়ার্ডো-আইভানেকের দেওয়া / পুনরায় সেট না করে দেওয়া উত্তরের উপর ভিত্তি করে IFS
, কেউ কেবল তা করতে পারে:
for i in "c 3" "e 5"
do
set -- $i
echo $1 and $2
done
আউটপুট:
c and 3
e and 5
সহযোগী অ্যারে (অভিধান / হ্যাশম্যাপ হিসাবে পরিচিত) ব্যবহার করুন:
declare -A pairs=(
[c]=3
[e]=5
)
for key in "${!pairs[@]}"; do
value="${pairs[$key]}"
echo "key is $key and value is $value"
done
Bash4.0 + এর জন্য কাজ করে।
আপনার যদি জোড়াগুলির পরিবর্তে ট্রিপলগুলির প্রয়োজন হয় তবে আপনি আরও সাধারণ পদ্ধতির ব্যবহার করতে পারেন:
animals=(dog cat mouse)
declare -A sound=(
[dog]=barks
[cat]=purrs
[mouse]=cheeps
)
declare -A size=(
[dog]=big
[cat]=medium
[mouse]=small
)
for animal in "${animals[@]}"; do
echo "$animal ${sound[$animal]} and it is ${size[$animal]}"
done
GNU bash, version 4.4.23(1)-release-(x86_64-apple-darwin17.5.0)
, যা মেশানো মাধ্যমে ইনস্টল করা হয়েছিল, তাই ওয়াইএমএমভি।
GNU bash, version 4.3.11(1)-release-(x86_64-pc-linux-gnu)
উবুন্টু থেকে 14.04 ডকের পাত্রে এটি কাজ করেছিল।
-A
আমাদের রয়েছে -a
।
declare -a indices=(1 2 3); declare -a sound=(barks purrs cheeps); declare -a size=(big medium small)
ইত্যাদি এখনও টার্মিনালে এটি চেষ্টা করেন নি, তবে আমার মনে হয় এটি কাজ করা উচিত।
c=('a' 'c')
n=(3 4 )
for i in $(seq 0 $((${#c[*]}-1)))
do
echo ${c[i]} ${n[i]}
done
কখনও কখনও আরও সহজ হতে পারে।
ugly
অংশটি ব্যাখ্যা করার জন্য , মন্তব্যে উল্লিখিত:
SeQ 0 2 তাই এই উদাহরণে আউটপুট জন্য, সংখ্যা ক্রম 0 থেকে 1 2. $ (cmd কমান্ড) কমান্ড প্রতিকল্পন হয় উৎপন্ন seq 0 2
, যা সংখ্যা ক্রম। তবে উপরের আবদ্ধটি $((${#c[*]}-1))
কী?
$ ((পারছেন)) গাণিতিক সম্প্রসারণ, তাই $ ((3 + 4)) হয় 7 ইত্যাদি আমাদের অভিব্যক্তি ${#c[*]}-1
যদি আমরা জানি কি, 1. সুন্দর সহজ -, তাই কিছু ${#c[*]}
নেই।
c একটি অ্যারে, সি [*] হ'ল পুরো অ্যারে, $ {# সি [*]। অ্যারের আকার যা আমাদের ক্ষেত্রে 2। এখন আমরা সবকিছু ফিরে পাকানো: for i in $(seq 0 $((${#c[*]}-1)))
হয় for i in $(seq 0 $((2-1)))
হয় for i in $(seq 0 1)
হয় for i in 0 1
। কারণ অ্যারের শেষ উপাদানটির একটি সূচক রয়েছে যা অ্যারের দৈর্ঘ্য - 1 1
for i in $(seq 0 $(($#c[*]}-1))); do [...]
জিএনইউ সমান্তরাল ব্যবহার:
parallel echo {1} and {2} ::: c e :::+ 3 5
বা:
parallel -N2 echo {1} and {2} ::: c 3 e 5
বা:
parallel --colsep , echo {1} and {2} ::: c,3 e,5
gnu parallel
brew install parallel
printf
প্রক্রিয়া প্রতিস্থাপনে ব্যবহার করা :
while read -r k v; do
echo "Key $k has value: $v"
done < <(printf '%s\n' 'key1 val1' 'key2 val2' 'key3 val3')
Key key1 has value: val1
Key key2 has value: val2
Key key3 has value: val3
উপরে প্রয়োজন bash
। যদি bash
ব্যবহার না করা হয় তবে সাধারণ পাইপলাইনটি ব্যবহার করুন:
printf '%s\n' 'key1 val1' 'key2 val2' 'key3 val3' |
while read -r k v; do echo "Key $k has value: $v"; done
do echo $key $value
done < file_discriptor
উদাহরণ স্বরূপ:
$ while read key value; do echo $key $value ;done <<EOF
> c 3
> e 5
> EOF
c 3
e 5
$ echo -e 'c 3\ne 5' > file
$ while read key value; do echo $key $value ;done <file
c 3
e 5
$ echo -e 'c,3\ne,5' > file
$ while IFS=, read key value; do echo $key $value ;done <file
c 3
e 5
আরও কিছুটা জড়িত, তবে এটি কার্যকর হতে পারে:
a='((c,3), (e,5))'
IFS='()'; for t in $a; do [ -n "$t" ] && { IFS=','; set -- $t; [ -n "$1" ] && echo i=$1 j=$2; }; done
তবে কি যদি কোনও সহযোগী অ্যারে ধরে রাখতে পারে কে / ভি এর তুলনায় টিপলটি বেশি হয়? যদি এটি 3 বা 4 উপাদান হয়? এই ধারণাটি প্রসারিত করতে পারে:
###---------------------------------------------------
### VARIABLES
###---------------------------------------------------
myVars=(
'ya1,ya2,ya3,ya4'
'ye1,ye2,ye3,ye4'
'yo1,yo2,yo3,yo4'
)
###---------------------------------------------------
### MAIN PROGRAM
###---------------------------------------------------
### Echo all elements in the array
###---
printf '\n\n%s\n' "Print all elements in the array..."
for dataRow in "${myVars[@]}"; do
while IFS=',' read -r var1 var2 var3 var4; do
printf '%s\n' "$var1 - $var2 - $var3 - $var4"
done <<< "$dataRow"
done
তারপরে আউটপুটটি এমন কিছু দেখাচ্ছে:
$ ./assoc-array-tinkering.sh
Print all elements in the array...
ya1 - ya2 - ya3 - ya4
ye1 - ye2 - ye3 - ye4
yo1 - yo2 - yo3 - yo4
এবং উপাদানের সংখ্যা এখন সীমা ছাড়াই। ভোট খুঁজছেন না; শুধু জোরে চিন্তা করছি। REF1 , REF2
আমার টিউপল সংজ্ঞাগুলি আরও জটিল, সেই ক্ষেত্রে আমি এগুলিকে বংশগতভাবে রাখাই পছন্দ করি:
while IFS=", " read -ra arr; do
echo "${arr[0]} and ${arr[1]}"
done <<EOM
c, 3
e, 5
EOM
এটি কোনও হেরডোকের লাইনের উপরে লুপিংকে কিছু পছন্দসই পৃথক চরিত্রের লাইনগুলি বিভক্ত করার সাথে একত্রিত করে ।