البرنامج النصي شل "for" بنية الحلقة

سئل على ١٨ سبتمبر ٢٠٠٩  ·  تمت مشاهدة 861.3k مرة  ·  مصدر

eykanal picture
في ١٨ سبتمبر ٢٠٠٩

لقد حصلت على ما يلي للعمل:

for i in {2..10}
do
    echo "output: $i"
done

ينتج مجموعة من السطور من output: 2 ، output: 3 ، وهكذا.

ومع ذلك ، نحاول تشغيل ما يلي:

max=10
for i in {2..$max}
do
    echo "$i"
done

تنتج ما يلي:

output: {2..10}

كيف يمكنني جعل المترجم يدرك أنه يجب أن يتعامل مع $ max على أنه الطرف الآخر من المصفوفة ، وليس جزءًا من سلسلة؟

الإجابات

whatsisname picture
في ١٨ سبتمبر ٢٠٠٩
237

توسيع الأقواس ، يتم تنفيذ للتسلسلات ذات الطول المتغير.

بدلا من ذلك، استخدم seq 2 $max الأسلوب كما الغوغاء المستخدم ذكر .

لذلك ، على سبيل المثال الخاص بك سيكون:

max=10
for i in `seq 2 $max`
do
    echo "$i"
done
system PAUSE picture
في ١٨ سبتمبر ٢٠٠٩
72

جرب إصدار التعبير الحسابي for :

max=10
for (( i=2; i <= $max; ++i ))
do
    echo "$i"
done

يتوفر هذا في معظم إصدارات bash ، ويجب أن يكون متوافقًا أيضًا مع Bourne shell (sh).

Nietzche-jou picture
في ١٨ سبتمبر ٢٠٠٩
28

خطوة الحلقة يدويًا:

 أنا = 0
 ماكس = 10
 بينما [$ i -lt $ max]
 فعل
 صدى "الإخراج: $ i"
 صحيح $ ((i ++))
 منجز

إذا لم يكن عليك أن تكون POSIX بالكامل ، فيمكنك استخدام الحساب for loop:

 ماكس = 10
 لـ ((i = 0 ؛ i <max ؛ i ++)) ؛ فعل صدى "الإخراج: $ i"؛ منجز

أو استخدم jot (1) في أنظمة BSD:

 بالنسبة إلى i بالدولار (ذرة 0 10) ؛ فعل صدى "الإخراج: $ i"؛ منجز
mob picture
في ١٨ سبتمبر ٢٠٠٩
9

إذا كان الأمر seq متوفرًا على نظامك:

for i in `seq 2 $max`
do
  echo "output: $i"
done

إذا لم يكن كذلك ، فاستخدم الرجل الفقير seq مع perl :

seq=`perl -e "\$,=' ';print 2..$max"`
for i in $seq
do
  echo "output: $i"
done

مشاهدة علامات الاقتباس تلك.

ephemient picture
في ١٨ سبتمبر ٢٠٠٩
9

هناك أكثر من طريقة للقيام بذلك.

max=10
for i in `eval "echo {2..$max}"`
do
    echo "$i"
done
Jahid picture
في ١٢ يوليو ٢٠١٥
5

هذه طريقة:
سحق:

max=10
for i in $(bash -c "echo {2..${max}}"); do echo $i; done

ستعمل طريقة Bash أعلاه مقابل ksh و zsh أيضًا ، عند استبدال bash -c بـ ksh -c أو zsh -c على التوالي.

ملاحظة: for i in {2..${max}}; do echo $i; done يعمل في zsh و ksh .

rashedcs picture
في ٢١ يوليو ٢٠١٨
5

يمكننا تكرار حلقة مثل برمجة C.

#!/bin/bash
for ((i=1; i<=20; i=i+1))
do 
      echo $i
done
eykanal picture
في ١٨ سبتمبر ٢٠٠٩
2

حسنًا ، نظرًا لعدم وجود الأمر seq مثبتًا على نظامي (Mac OS X v10.6.1 (Snow Leopard)) ، انتهى بي الأمر باستخدام حلقة while بدلاً من ذلك:

max=5
i=1

while [ $max -gt $i ]
do
    (stuff)
done

* يتجاهل * كل ما يصلح.

minhas23 picture
في ٦ ديسمبر ٢٠١٣
2

عملت هنا على نظام التشغيل Mac OS X.

يتضمن مثالًا لتاريخ BSD ، وكيفية زيادة التاريخ وإنقاصه أيضًا:

for ((i=28; i>=6 ; i--));
do
    dat=`date -v-${i}d -j "+%Y%m%d"` 
    echo $dat
done
Chris Dodd picture
في ١٨ سبتمبر ٢٠٠٩
1

استعمال:

max=10
for i in `eval echo {2..$max}`
do
    echo $i
done

أنت بحاجة إلى استدعاء "Eval" الصريح لإعادة تقييم {} بعد استبدال المتغير.