একটি লুপে দুটি সিকোয়েন্সের মধ্য দিয়ে চলুন


8

আমি নীচের মতো আমার শেলের একই লুপটিতে দুটি ক্রম চালানোর চেষ্টা করছি:

#!/bin/bash
for i in (1..15) and (20..25) ;
do
     echo $i
     ......
     .....other process
done

কোন ধারণা আমি কীভাবে এটি অর্জন করতে পারি?


@ জাজান্না - আমার প্রথম চিন্তাটি হল যে বুলিয়ান "এবং" একচেটিয়া, যার অর্থ ফলাফলটি উভয় সেটে বিদ্যমান সংখ্যাগুলি; যা এই ক্ষেত্রে কিছুই নয়। একটি অন্তর্ভুক্ত "এবং" আছে কি?
রাভারি

1
@ প্রতিলিপি আমি "এবং" আমি কী খুঁজছি তা ব্যাখ্যা করার জন্য
HISI

2
@ ইয়াসাইনসিহি - ভাল নোট করুন অনেকগুলি নতুন প্রোগ্রামার তাদের মস্তিষ্ককে পুনরায় প্রশিক্ষণ না দেওয়া পর্যন্ত এই পয়েন্টে হোঁচট খাচ্ছেন, কারণ কথ্য ভাষাটি বেশিরভাগ প্রোগ্রামিং ভাষায় "এবং" অন্তর্ভুক্ত তবে যৌক্তিক "এবং" একচেটিয়া ব্যবহার করে।
রাভারি

উত্তর:


10

তার জন্য আপনার কেবল ব্রেস সম্প্রসারণ প্রয়োজন

$ 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 আপনার কেবল তাদের মধ্যে একটি স্পেস স্থাপন করা উচিত, যেহেতু শেলগুলি সেগুলিতে যুক্তিগুলির তালিকা বিভক্ত করে।


হ্যাঁ, ধনুর্বন্ধনী। । । আর তুমি এমনকি যে ^ _0 জন্য একটি লুপ প্রয়োজন হবে না
Sergiy Kolodyazhnyy

@ সের্গি কলোডিএজনি আমি অনুমান করি যে তারা আসলে echoসংখ্যায় চায় না
জ্যানা ২

হ্যাঁ, যদি তারা কোনও ধরণের ক্রিয়া touchকরতে চায় তবে ফাইলের মতো তারা এগুলি করতে পারে touch {1..15}.txt {20..25}.txt, এখানে কোনও লুপের প্রয়োজন নেই। তবে অবশ্যই যদি এটি একই সংখ্যার একাধিক ক্রিয়া হয় - ঠিক আছে, এটি একটি লুপ ব্যবহার করতে পারে।
সের্গেই কলডিয়াজনি

6

বিকল্পভাবে আমরা ব্যবহার করতে পারি 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"

4

জান্নার উত্তর এবং প্যার 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

@ সার্জি কলোডিএজনি: মতামতকে ধন্যবাদ আমার যথেষ্ট বয়স হয়েছে যে আমাকে এভাবেই শিখানো হয়েছিল, এবং এখনও প্রায়শই বিরল উপলক্ষে আমি শেল স্ক্রিপ্ট লিখছি do তবে, আমি একটি অ্যারের ব্যবহার করার জন্য উত্তর আপডেট করেছি।
গ্রিনম্যাট

খুব ভাল ! শুভ স্ক্রিপ্টিং!
সের্গেই কলডিয়াজনি

3

লুপ ছাড়াই লুপিং

জান্নার উত্তরটি একেবারে সঠিক এবং ব্যাশের জন্য উপযুক্ত, তবে আমরা একটি লুপ ব্যবহার না করে আরও বেশি উন্নতি করতে পারি।

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

1
আমি সবেমাত্র পরীক্ষা করেছি touch $(printf "%d\n" {1..15} {20..25}):-)
pa4080

1
@ Pa4080 আসলে bashআপনার $()কেবল সেখানে দরকার নেই কেবল touch {1..15}.txt {20..25}.txt :) তবে অবশ্যই আমরা যদি কেবল ফাইলগুলি ছাড়া আরও কিছু করতে চাই তবে আমরা printf "%d\n{1..15} .. 20..25} use ব্যবহার xargsকরতে পারি touch। জিনিসগুলি করার অনেকগুলি উপায় রয়েছে এবং এটি স্ক্রিপ্টিংটিকে এত মজা দেয়!
সের্গেই কোলোডিয়াজনি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.