البرمجة البرمجة البرمجية لبورن شل - بسيطة لبناء الحلقات

StackOverflow https://stackoverflow.com/questions/1783961

سؤال

أنا لست جديدًا تمامًا في البرمجة ، لكنني لست من ذوي الخبرة بالضبط. أريد أن أكتب نص قذيفة صغير للممارسة.

هذا ما لدي حتى الآن:

#!/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"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top