আমি নীচের মতো আমার শেলের একই লুপটিতে দুটি ক্রম চালানোর চেষ্টা করছি:
#!/bin/bash
for i in (1..15) and (20..25) ;
do
echo $i
......
.....other process
done
কোন ধারণা আমি কীভাবে এটি অর্জন করতে পারি?
আমি নীচের মতো আমার শেলের একই লুপটিতে দুটি ক্রম চালানোর চেষ্টা করছি:
#!/bin/bash
for i in (1..15) and (20..25) ;
do
echo $i
......
.....other process
done
কোন ধারণা আমি কীভাবে এটি অর্জন করতে পারি?
উত্তর:
তার জন্য আপনার কেবল ব্রেস সম্প্রসারণ প্রয়োজন
$ for n in {1..3} {200..203}; do echo $n; done
1
2
3
200
201
202
203
আমরা for
( ) তে একটি তালিকা পাস করতে পারি ।for i in x y z; do stuff "$i"; done
সুতরাং এখানে, ধনুর্বন্ধকগুলি {
}
আপনার ক্রমগুলি তালিকায় প্রসারিত করতে শেলটি পায় get আপনার কেবল তাদের মধ্যে একটি স্পেস স্থাপন করা উচিত, যেহেতু শেলগুলি সেগুলিতে যুক্তিগুলির তালিকা বিভক্ত করে।
echo
সংখ্যায় চায় না
touch
করতে চায় তবে ফাইলের মতো তারা এগুলি করতে পারে touch {1..15}.txt {20..25}.txt
, এখানে কোনও লুপের প্রয়োজন নেই। তবে অবশ্যই যদি এটি একই সংখ্যার একাধিক ক্রিয়া হয় - ঠিক আছে, এটি একটি লুপ ব্যবহার করতে পারে।
বিকল্পভাবে আমরা ব্যবহার করতে পারি seq
( সংখ্যার ক্রম মুদ্রণ ), এখানে দুটি সমতুল উদাহরণ:
for i in `seq 1 3` `seq 101 103`; do echo $i; done
for i in $(seq 1 3) $(seq 101 103); do echo $i; done
যদি এটি কোনও স্ক্রিপ্ট হয় তবে পুনরাবৃত্তিযোগ্য কাজের জন্য, আপনি ফাংশনগুলি ব্যবহার করতে পারেন:
#!/bin/bash
my_function() { echo "$1"; }
for i in {1..3}; do my_function "$i"; done
for i in {101..103}; do my_function "$i"; done
#!/bin/bash
my_function() { for i in `seq $1 $2`; do echo "$i"; done; }
my_function "1" "3"
my_function "101" "103"
জান্নার উত্তর এবং প্যার 4080 এর উত্তর উভয়ই ভাল এবং আমি সম্ভবত বেশিরভাগ পরিস্থিতিতে তাদের একটির সাথে যেতে পারি। সম্ভবত এটি বলার অপেক্ষা রাখে না, তবে সম্পূর্ণতার জন্য, আমি যাই হোক না কেন এটি বলব: আপনি প্রতিটি মান একটি অ্যারেতে লোড করতে পারেন এবং তারপরে অ্যারের উপরে লুপ করতে পারেন। উদাহরণ স্বরূপ:
the_array=( 1 2 3 4 5 6 7 8 9 10 20 21 22 23 24 25 )
for i in "${the_array[@]}";
do
echo $i
done
জান্নার উত্তরটি একেবারে সঠিক এবং ব্যাশের জন্য উপযুক্ত, তবে আমরা একটি লুপ ব্যবহার না করে আরও বেশি উন্নতি করতে পারি।
printf "%d\n" {1..15} {20..25}
আচরণটি printf
এমন যে, যদি সংখ্যাটি ARGUMENTS
বিন্যাসের নিয়ন্ত্রণের চেয়ে বেশি হয় 'FORMAT STRING'
তবে সমস্তগুলি সমান অংশে printf
বিভক্ত ARGUMENTS
করে ফর্ম্যাট স্ট্রিংয়ে ARGUMENTS
তালিকাটি শেষ না হওয়া পর্যন্ত এগুলি ফিট করে রাখবে ।
আমরা যদি বহনযোগ্যতার জন্য প্রচেষ্টা চালিয়ে যাচ্ছি তবে আমরা এর printf "%d\n" $(seq 1 15) $(seq 20 25)
পরিবর্তে ব্যবহার করতে পারি
এর আরও এবং আরও মজা করা যাক। বলুন আমরা কেবল সংখ্যা মুদ্রণের চেয়ে একটি ক্রিয়া সম্পাদন করতে চাই। সংখ্যার ক্রম থেকে ফাইল তৈরি করার জন্য, আমরা সহজেই করতে পারি touch {1..15}.txt {20..25}.txt
। আমরা যদি একাধিক জিনিস ঘটতে চাই? আমরা এর মতো কিছু করতে পারি:
$ printf "%d\n" {1..15} {20..25} | xargs -I % bash -c 'touch "$1.txt"; stat "$1.txt"' sh %
বা যদি আমরা এটি পুরাতন-স্কুল স্টাইল করতে চাই:
printf "%d\n" {1..15} {20..25} | while read -r line; do
touch "$line".txt;
stat "$line".txt;
rm "$line".txt;
done
যদি আমরা এমন কোনও স্ক্রিপ্ট সমাধান করতে চাই যা ব্রেস সম্প্রসারণ না করে এমন শেলগুলির সাথে কাজ করে (যা এটি {1..15} {20..25}
নির্ভর করে) তবে আমরা একটি সহজ লুপ লিখতে পারি:
#!/bin/sh
start=$1
jump=$2
new_start=$3
end=$4
i=$start
while [ $i -le $jump ]
do
printf "%d\n" "$i"
i=$((i+1))
if [ $i -eq $jump ] && ! [ $i -eq $end ];then
printf "%d\n" "$i"
i=$new_start
jump=$end
fi
done
অবশ্যই এই সমাধানটি আরও ভার্বোজ, কিছু জিনিস সংক্ষিপ্ত করা যেতে পারে, তবে এটি কার্যকর হয়। সাথে পরীক্ষিত ksh
, dash
, mksh
, এবং অবশ্যই bash
।
তবে আমরা যদি একটি লুপ ব্যাশ-নির্দিষ্ট করতে চাই (যে কোনও কারণেই, সম্ভবত কেবল মুদ্রণ নয় তবে সেই সংখ্যাগুলির সাথে কিছু করাও), আমরা এটিও করতে পারি (মূলত বহনযোগ্য সমাধানের সি-লুপ সংস্করণ):
last=15; for (( i=1; i<=last;i++ )); do printf "%d\n" "$i"; [[ $i -eq $last ]] && ! [[ $i -eq 25 ]] && { i=19;last=25;} ;done
বা আরও পাঠযোগ্য বিন্যাসে:
last=15
for (( i=1; i<=last;i++ ));
do
printf "%d\n" "$i"
[[ $i -eq $last ]] && ! [[ $i -eq 25 ]] && { i=19;last=25;}
done
bash-4.3$ time bash -c 'printf "%d\n" {0..50000}>/dev/null'
real 0m0.196s
user 0m0.124s
sys 0m0.028s
bash-4.3$ time bash -c 'for i in {1..50000}; do echo $i > /dev/null; done'
real 0m1.819s
user 0m1.328s
sys 0m0.476s
bash-4.3$ time bash -c ' i=0;while [ $i -le 50000 ]; do echo $i>/dev/null; i=$((i+1)); done'
real 0m3.069s
user 0m2.544s
sys 0m0.500s
bash-4.3$ time bash -c 'for i in $(seq 1 50000); do printf "%d\n" > /dev/null; done'
real 0m1.879s
user 0m1.344s
sys 0m0.520s
কেবল কারণ আমরা এখানে পাইথন সমাধান করতে পারি
$ python3 -c 'print("\n".join([str(i) for i in (*range(1,16),*range(20,26))]))'
অথবা কিছুটা শেল দিয়ে:
bash-4.3$ python3 << EOF
> for i in (*range(16),*range(20,26)):
> print(i)
> EOF
touch $(printf "%d\n" {1..15} {20..25})
:-)
bash
আপনার $()
কেবল সেখানে দরকার নেই কেবল touch {1..15}.txt {20..25}.txt
:) তবে অবশ্যই আমরা যদি কেবল ফাইলগুলি ছাড়া আরও কিছু করতে চাই তবে আমরা printf "%d\n
{1..15} .. 20..25} use ব্যবহার xargs
করতে পারি touch
। জিনিসগুলি করার অনেকগুলি উপায় রয়েছে এবং এটি স্ক্রিপ্টিংটিকে এত মজা দেয়!