حلقة for في Bash
كيفية عمل حلقة for التكرارية
حلقة for هي أول وحدة تكرارية في الصدفة من بين ثلاث وحدات، وتسمح تلك الحلقة بتخصيص قائمة من القِيَم، وتُنفَّذ قائمة من الأوامر لكل قيمة من تلك القيم.
والبنية اللغوية لهذه الحلقة التكرارية هي كالآتي:
for NAME [in LIST ]; do COMMANDS; done
إن لم تكن [ in LIST]
موجودة فيتم استبدال @$ in
بها، وتنفذ for
الأوامر (COMMANDS
) مرة واحدة لكل معامل موضعي مضبوط على قيمة، انظر المتغيرات في Bash وفحص وسائط سطر الأوامر.
وتكون حالة الإعادة (return status) هي حالة الخروج لآخِر أمر يُنفّذ، وإن لم يُنفذ أي أمر بسبب أن LIST
لا تتوسع إلى أي عنصر فإن حالة الإعادة هي صفر.
ويمكن أن يكون الاسم (NAME
) أي اسم لمتغير رغم أن i
تستخدم كثيرًا، وكذلك يمكن أن تكون قائمة (LIST
) مكونة من أي كلمات أو نصوص أو أرقام، والتي قد تكون حرفية أو مولَّدة بواسطة أي أمر.
وبالمثل فإن الأوامر التي يجب تنفيذها لكل قيمة (COMMANDS
) يمكن أن تكون أي أوامر للنظام أو برامج أو عبارات للصدفة (shell statement) أو برامج للصدفة (scripts) أيضًا. وعند بدء أول دورة في الحلقة يُضبط متغير NAME
في أول مرة على أول عنصر في قائمة LIST
، ثم تتغير قيمته في المرة الثانية إلى ثاني عنصر في القائمة، وهكذا. تنتهي الحلقة التكرارية حين ينتهي متغير NAME
من المرور على كل القيم في القائمة.
أمثلة
استخدام استبدال الأوامر لتحديد عناصر القائمة
سيكون أول مثال على سطر الأوامر، حيث يعرض استخدام حلقةُ for
لإنشاء نسخة احتياطية من كل ملف xml.
، ويمكنك العمل على مصادرك بأمان بعد إصدار الأمر:
[wiki@hsoub ~/articles] ls *.xml
file1.xml file2.xml file3.xml
[wiki@hsoub ~/articles] ls *.xml > list
[wiki@hsoub ~/articles] for i in `cat list`; do cp "$i" "$i".bak ; done
[wiki@hsoub ~/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 يضيفان سطري ترويسة وتذييل:
[wiki@hsoub ~/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