ব্যাশে, লুপের জন্য লুপ নিয়ন্ত্রণে কোনও পূর্ণসংখ্যের পরিবর্তনশীল ব্যবহার করা সম্ভব?


65

আমার কাছে নিম্নলিখিত বাশ স্ক্রিপ্ট রয়েছে:

#!/bin/bash

upperlim=10

for i in {0..10}
do
echo $i
done

for i in {0..$upperlim}
do
echo $i
done

প্রথম forলুপ ( লুপ নিয়ন্ত্রণে পরিবর্তনশীল ব্যতীতupperlim ) ভাল কাজ করে, তবে দ্বিতীয় forলুপ ( লুপ নিয়ন্ত্রণে ভেরিয়েবল সহupperlim ) কার্যকর হয় না। forএটির কোনও উপায় আছে যে আমি দ্বিতীয় লুপটি সংশোধন করতে পারি যাতে এটি কাজ করে? আপনার সময় জন্য ধন্যবাদ।


4
এইচএম, এমনকি for i in {0..$((upperlim))}; do echo $i; doneকাজ করে না
— বনসি স্কট

এবং +1 কারণ আমি সেই আচরণটি আকর্ষণীয় মনে করি
— বনসি স্কট

এর সম্ভাব্য ক্রস সাইটের সদৃশ: স্ট্যাকওভারফ্লো.
— com/ জিজ্ঞাসা / ১69৯৫11/…

একটি বাহ্যিক লিঙ্ক যে এই উত্তর দেয়: cyberciti.biz/faq/...
— কন Psych

উত্তর:


62

এর কারণ হ'ল আদেশটি যাতে জিনিসগুলিতে বাশ হয়। ভেরিয়েবলগুলি প্রসারিত হওয়ার আগে ব্রেস সম্প্রসারণ ঘটে । আপনার লক্ষ্যটি অর্জন করতে, আপনাকে লুপের জন্য সি-স্টাইল ব্যবহার করতে হবে:

upperlim=10

for ((i=0; i<=upperlim; i++)); do
   echo "$i"
done

1
আর জন্য কাজ করে zsh(কিন্তু না পাশাপাশি csh, tcsh)।
— গণিত

29

আপনার শৈলীতে এটি বিল্ট-ইনগুলি ব্যতীত অন্য কিছু ব্যবহার করে সম্পূর্ণ করতে আপনাকে ওয়াল ব্যবহার করতে হবে:

d=12

for i in `eval echo {0..$d}`
do
echo $i
done

তবে সাথে seq:

lowerlimit=0
upperlimit=12

for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done

ব্যক্তিগতভাবে আমি seqআরও পঠনযোগ্য হতে ব্যবহারটি খুঁজে পাই ।


"বিল্ট-ইনস" এর জন্য? seqএটি একটি বাহ্যিক কমান্ড এবং বশ যেখানেই পাওয়া যায় না।
— জর্ডানম

9
@ জোর্ডানম: বাশ সহ সমস্ত বিল্টিন ব্যবহার করার জন্য। তারপরে আমি বললাম "তবে সাথে seq", স্বীকৃতি দিয়েছিলাম যে এটি কোনও অন্তর্নির্মিত নয়।
— Jodie সি

ব্রেস সম্প্রসারণ অন্তর্নির্মিত হয় তা এখানে সমস্যা নয়। readউদাহরণস্বরূপ একটি বিল্টিন, তবে evalএটির কোনও কারণ নেই ।
— জর্ডানম

1
বিল্টিনগুলি মোটেই সমস্যাযুক্ত নয়। আমি জিজ্ঞাসাকারীর জন্য একটি সর্ব-বাশ সমাধান সরবরাহ করতে চেয়েছিলাম। আপনি যদি এই বিষয়ে তর্ক চালিয়ে যেতে চান তবে এটি চ্যাটে নিয়ে যান; মন্তব্যগুলি এই ধরণের জন্য ভাল নয়
— Jodie সি

8

POSIX উপায়

আপনি যদি বহনযোগ্যতার বিষয়ে যত্নশীল হন তবে পসিক্স মান থেকে উদাহরণটি ব্যবহার করুন :

i=2
END=5
while [ $i -le $END ]; do
    echo $i
    i=$(($i+1))
done

আউটপুট:

2
3
4
5

যে জিনিসগুলি পসিক্স নয় :

  • (( ))ডলার ব্যতীত, যদিও এটি পসিক্স নিজেই উল্লিখিত একটি সাধারণ এক্সটেনশন ।
  • [[। [এখানে যথেষ্ট। আরও দেখুন: https://stackoverflow.com
  • for ((;;))
  • seq
  • {start..end}, এবং এটি ব্যাশ ম্যানুয়াল অনুসারে ভেরিয়েবলগুলির সাথে কাজ করতে পারে না ।
  • let i=i+1: পজিক্স 7 2. শেল কমান্ড ভাষা শব্দটি ধারণ করে না letএবং এটি bash --posix4.3.42 এ ব্যর্থ হয়
  • ডলার i=$i+1প্রয়োজন হতে পারে, কিন্তু আমি নিশ্চিত না। পসিক্স 7 2.6.4 গাণিতিক সম্প্রসারণ বলেছেন:

    শেল ভেরিয়েবল এক্সে যদি এমন কোনও মান থাকে যা বৈধ পূর্ণসংখ্যক ধ্রুবক গঠন করে, allyচ্ছিকভাবে একটি শীর্ষস্থানীয় প্লাস বা বিয়োগ চিহ্ন সহ, তবে পাটিগণিতের বিস্তৃতি "$((x))"এবং "$(($x))"একই মানটি প্রত্যাবর্তন করে।

    তবে এটি আক্ষরিকভাবে পড়া যা বোঝায় না যে এটি $((x+1))প্রসারিত x+1হয় না কারণ এটি পরিবর্তনশীল নয়।


1

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

আপনি eval সঙ্গে প্রায় কাজ করতে পারেন :

upperlim=10
eval '
        for i in {0..'"$upperlim"'}
        do
                echo $i
        done
'

সঙ্গে যখন লুপ :

upperlim=10
#with while
start=0
while [[ $start -le $upperlim ]]
do
    echo "$start"
    ((start = start + 1))
done

এছাড়াও আপনি এটি সেক কমান্ড দিয়ে করতে পারেন :

upperlim=10
#seq
for i in $(seq "$upperlim"); do
  echo "$i"
done

আপনি যদি চালাতে চান তবে আপনাকে for i in {0..$upperlim}কর্নশেল ব্যবহার করতে হবে। উদাহরণ:

#!/bin/ksh
upperlim=10

for i in {0..$upperlim}
do
        echo $i
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.