البرمجة البرمجة البرمجية لبورن شل - بسيطة لبناء الحلقات
سؤال
أنا لست جديدًا تمامًا في البرمجة ، لكنني لست من ذوي الخبرة بالضبط. أريد أن أكتب نص قذيفة صغير للممارسة.
هذا ما لدي حتى الآن:
#!/bin/sh
name=$0
links=$3
owner=$4
if [ $# -ne 1 ]
then
echo "Usage: $0 <directory>"
exit 1
fi
if [ ! -e $1 ]
then
echo "$1 not found"
exit 1
elif [ -d $1 ]
then
echo "Name\t\tLinks\t\tOwner\t\tDate"
echo "$name\t$links\t$owner\t$date"
exit 0
fi
في الأساس ما أحاول القيام به هو جعل البرنامج النصي يمر بجميع الملفات في دليل محدد ، ثم عرض اسم كل ملف بمقدار الروابط التي يمتلكها ، ومالكه ، والتاريخ الذي تم إنشاؤه فيه. ماذا سيكون بناء الجملة لعرض تاريخ الإنشاء أو على الأقل تاريخ التعديل الأخير للملف؟
شيء آخر هو ، ما هو بناء الجملة لإنشاء حلقة؟ من ما أفهمه ، سأضطر إلى كتابة شيء مثل دولار واحد في دولار واحد (1 دولار كونه جميع الملفات في الدليل الذي كتبه المستخدم بشكل صحيح؟) ثم انتقل إلى التحقق من كل ملف وعرض المعلومات لكل واحد. كيف يمكنني أن أبدأ وإنهاء الحلقة (ما هو بناء الجملة لهذا؟).
كما ترون ، فأنا لست مألوفًا جدًا لبرمجة بورن شل. إذا كان لديك أي مواقع ويب مفيدة أو لديك طريقة أفضل للاقتراب من هذا ، فيرجى إظهارها!
المحلول
بناء الجملة للحلقة:
for var in list
do
echo $var
done
فمثلا:
for var in *
do
echo $var
done
ما قد ترغب في التفكير فيه هو شيء من هذا القبيل:
ls -l | while read perms links owner group size date1 date2 time filename
do
echo $filename
done
الذي يقسم إخراج ls -l
في الحقول في حالة حدوثها حتى لا تحتاج إلى القيام بأي تقسيم بنفسك.
يتم التحكم في تقسيم الحقل بواسطة IFS المتغير ، والذي يحتوي بشكل افتراضي على مساحة وعلامة تبويب وخط جديد. إذا قمت بتغيير هذا في نص Shell ، تذكر تغييره مرة أخرى. وبالتالي عن طريق تغيير قيمة IFS ، يمكنك ، على سبيل المثال ، تحليل ملفات CSV عن طريق تعيين هذا على فاصلة. يقرأ هذا المثال ثلاثة حقول من CSV ويبصق في الثانية والثالثة فقط (وهو ما يعادل القشرة بشكل فعال cut -d, -f2,3 inputfile.csv
)
oldifs=$IFS
IFS=","
while read field1 field2 field3
do
echo $field2 $field3
done < inputfile.csv
IFS=oldifs
(ملاحظة: أنت لا تفعل بحاجة إلى للعودة إلى IFS ، لكنني أفعل عمومًا للتأكد من أن معالجة النصوص الإضافية في البرنامج النصي لا تتأثر بعد انتهائي من ذلك).
الكثير من الوثائق على حد سواء for
و while
حلقات فقط جوجل لذلك :-)
نصائح أخرى
قد ترغب في النظر إلى دليل الدفاع المتقدم باش. لديه قسم يفسر الحلقات.
أقترح استخدام find
مع الخيار -printf "%P\t%n\t%u\t%t"
$1
هي المعلمة الموضعية الأولى ، لذلك $3
هو الثالث و $4
هو الرابع. لا علاقة لهم بالدليل (أو ملفاته) بدأ البرنامج النصي منه. إذا بدأ البرنامج النصي باستخدام هذا ، على سبيل المثال:
./script.sh apple banana cherry date elderberry
ثم المتغير $1
سوف تساوي "التفاح" وهلم جرا. المعلمة الخاصة $#
هو عدد المعلمات الموضعية ، والتي في هذه الحالة ستكون خمسة.
يوجد اسم البرنامج النصي في $0
و $*
و $@
هي المصفوفات التي تحتوي على جميع المعلمات الموضعية التي تتصرف بشكل مختلف اعتمادًا على ما إذا كانت تظهر في عروض الأسعار.
يمكنك الرجوع إلى المعلمات الموضعية باستخدام فهرس على غرار السلسلة الفرعية:
${@:2:1}
سيعطي "الموز" باستخدام المثال أعلاه. و:
${@: -1}
أو
${@:$#}
سوف يعطي آخر ("كبار السن"). لاحظ أن المساحة قبل علامة ناقص مطلوبة في هذا السياق.
for x in "$@"; do
echo "$x"
done
يحمي "$@" أي مساحة بيضاء في أسماء الملفات الموردة. من الواضح ، قم بعمل عملك الحقيقي بدلاً من "Echo $ X" ، وهو ما لا يفعل الكثير. ولكن $@ هو كل غير المرغوب فيه على سطر الأوامر إلى البرنامج النصي الخاص بك.
ولكن أيضًا ، ينقذ البرنامج النصي إذا كان $# لا يساوي 1 ، لكن يبدو أنك تتوقع تمامًا ما يصل إلى 4 وسيطات (ومن هنا كانت الإشارة إلى 4 دولارات في الجزء الأول من البرنامج النصي).
على افتراض أن لديك GNU تجدها على نظامك
find /path -type f -printf "filename: %f | hardlinks: %n| owner: %u | time: %TH %Tb %TY\n"