حلقة for في Bash

من موسوعة حسوب


كيفية عمل حلقة for التكرارية

حلقة for هي أول وحدة تكرارية في الصدفة من بين ثلاث وحدات، وتسمح تلك الحلقة بتخصيص قائمة من القِيَم، وتُنفَّذ قائمة من الأوامر لكل قيمة من تلك القيم.

والبنية اللغوية لهذه الحلقة التكرارية هي كالآتي:

for NAME [in LIST ]; do COMMANDS; done

إن لم تكن [ in LIST] موجودة فيتم استبدال @$ in بها، وتنفذ for الأوامر (COMMANDS) مرة واحدة لكل معامل موضعي مضبوط على قيمة، انظر المتغيرات في Bash ومقدمة إلى if في Bash.

وتكون حالة الإعادة (return status) هي حالة الخروج لآخِر أمر يُنفّذ، وإن لم يُنفذ أي أمر بسبب أن LIST لا تتوسع إلى أي عنصر فإن حالة الإعادة هي صفر.

ويمكن أن يكون الاسم (NAME) أي اسم لمتغير رغم أن i تستخدم كثيرًا، وكذلك يمكن أن تكون قائمة (LIST) مكونة من أي كلمات أو نصوص أو أرقام، والتي قد تكون حرفية أو مولَّدة بواسطة أي أمر.

وبالمثل فإن الأوامر التي يجب تنفيذها لكل قيمة (COMMANDS) يمكن أن تكون أي أوامر للنظام أو برامج أو عبارات للصدفة (shell statement) أو برامج للصدفة (scripts) أيضًا. وعند بدء أول دورة في الحلقة يُضبط متغير NAME في أول مرة على أول عنصر في قائمة LIST، ثم تتغير قيمته في المرة الثانية إلى ثاني عنصر في القائمة، وهكذا. تنتهي الحلقة التكرارية حين ينتهي متغير NAME من المرور على كل القيم في القائمة.

أمثلة

استخدام استبدال الأوامر لتحديد عناصر القائمة

سيكون أول مثال على سطر الأوامر، حيث يعرض استخدام حلقةُ for لإنشاء نسخة احتياطية من كل ملف xml.، ويمكنك العمل على مصادرك بأمان بعد إصدار الأمر:

[hsoub@alaraby ~/articles] ls *.xml
file1.xml  file2.xml  file3.xml

[hsoub@alaraby ~/articles] ls *.xml > list

[hsoub@alaraby ~/articles] for i in `cat list`; do cp "$i" "$i".bak ; done

[hsoub@alaraby ~/articles] ls *.xml*
file1.xml  file1.xml.bak  file2.xml  file2.xml.bak  file3.xml  file3.xml.bak

أما هذا المثال فيعرض ملفات النصوص العادية والتي يحتمل أن تكون برامج، داخل مجلد sbin/ :

for i in `ls /sbin`; do file /sbin/$i | grep ASCII; done

استخدام محتوى المتغير لتحديد عناصر القائمة

ما يلي هو برنامج محدد يحوّل ملفات HTML متوافقة مع نظام ما إلى ملفات PHP، ويتم التحويل بحذف أول 25 سطر وآخر 21، ووضع وسمين من PHP يضيفان سطري ترويسة وتذييل:

[hsoub@alaraby ~/html] cat html2php.sh
#!/bin/bash
# php إلى html برنامج محدد لتحويل ملفات 
LIST="$(ls *.html)"
for i in "$LIST"; do
     NEWNAME=$(ls "$i" | sed -e 's/html/php/')
     cat beginfile > "$NEWNAME"
     cat "$i" | sed -e '1,25d' | tac | sed -e '1,21d'| tac >> "$NEWNAME"
     cat endfile >> "$NEWNAME"
done

ولا توجد طريقة لمعرفة رقم السطر الذي سيبدأ الحذف عنده إلا عند الوصول للنهاية لأننا لا نعُدّ الأسطر هنا، وتُحل المشكلة باستخدام tac حيث يعكس الأسطر داخل الملف.

أمر basename

من الأفضل استخدام أمر basename لتغيير لاحقة html إلى php. انظر صفحات دليل man لهذا الأمر للمزيد من التفصيل.

المحارف الشاذة

ستطرأ لديك مشاكل إن توسعت القائمة إلى أسماء ملفات بها محارف خاصة مثل المسافات وغيرها من المحارف الشاذة، والحل هنا أن تستخدم خاصية التدوير (globbing) في الصدفة كما يلي:

for i in $PATHNAME/*; do
	commands
done

انظر أيضًا

تنقيح برامج Bash.

التوسعات في Bash.

أمثلة عن استخدام grep.

مصادر

دليل Bash للمبتدئين. حلقة for التكرارية.