المسارات
/
AWK
AWK
/
المنهج
/
المبادئ الأساسية
ال

المبادئ الأساسية في AWK

1 تمرين

نبذة عن المبادئ الأساسية

سنشير إلى اللغة باسم AWK، وإلى البرنامج التنفيذي الذي يفسّر برامج AWK باسم awk أو gawk.

الأنماط والإجراءات

يتكوّن برنامج AWK من أزواج النمط والإجراء

pattern1 { action1 }
pattern2 { action2 }
...

يمكن أن يكون النمط تعبيرًا نمطيًا تُطابَق به بيانات الإدخال. ويمكن أن يكون أيضًا أي تعبير يُنتج قيمة صحيحة أو خاطئة.

الإجراء هو أمر AWK واحد أو أكثر. والأقواس المعقوفة المحيطة به إلزامية.

إذا كانت نتيجة النمط صحيحة، يُقيَّم الإجراء المقابل.

السجلات والحقول

يحلّل AWK الإدخال على شكل تسلسل من السجلات. ويُقسَّم كل سجل إلى حقول قد تكون صفرًا أو أكثر.

السلوك الافتراضي هو:

  • تقسيم الإدخال إلى سجلات باستخدام محرف السطر الجديد "فاصلًا للسجل"، فيكون كل سطر سجلًا.
  • تقسيم السجل إلى حقول باستخدام المسافات البيضاء "فاصلًا للحقل"، فتكون كل كلمة حقلًا.

الأنماط والإجراءات (تابع)

يمكن حذف النمط، وفي هذه الحالة يُقيَّم الإجراء لكل سجل من سجلات الإدخال.

ويمكن حذف الإجراء، وفي هذه الحالة يكون الإجراء الافتراضي هو طباعة السجل الحالي.

أنماط خاصة

هناك نمطان خاصان يُستخدمان كثيرًا.

  • يقيّم BEGIN الإجراء المرتبط به قبل استهلاك أي إدخال.
  • يقيّم END الإجراء المرتبط به بعد استهلاك كل الإدخال.

متغيرات الحقول

تشير إلى الحقول بالصيغة $1 و$2 و$3 وهكذا.

والسجل الحالي هو $0.

Caution

لنكن واضحين: هذه ليست "متغيرات" بالمعنى الدقيق. يمكن اعتبار $ عاملًا يجلب قيمة رقم الحقل المعطى. وسنتعمّق في هذا في مفاهيم لاحقة.

وإليك بعض المتغيرات المدمجة الأخرى كثيرة الاستخدام.

متغيرات مدمجة تتحكم في تحليل الإدخال

  • RS هو فاصل سجل الإدخال. وكما ذُكر، قيمته الافتراضية محرف سطر جديد.
  • FS هو فاصل حقل الإدخال.

غالبًا ما تُضبط هذه المتغيرات في كتلة إجراء BEGIN.

متغيرات مدمجة تنقل المعلومات

يضبط AWK هذه المتغيرات تلقائيًا أثناء تنفيذ البرنامج.

  • يخزّن NF عدد الحقول في السجل الحالي.
    • للحصول على قيمة الحقل الأخير، استخدم $NF.
  • يخزّن NR رقم السجل الحالي.
    • عند معالجة عدة ملفات إدخال، يحمل NR العدد الإجمالي للسجلات المعالجة حتى الآن.
  • يخزّن FNR رقم السجل الحالي في ملف الإدخال الحالي.
    • ولتوضيح الفرق بين NR وFNR، إليك تعبيرًا شائعًا في AWK.
      NR == FNR {action}
      
      أي: "إذا كان رقم السجل المتراكم يساوي رقم السجل في الملف الحالي". ولا يصح هذا إلا لسجلات ملف الإدخال الأول.

صحّة القيم

يستخدم AWK المفهوم نفسه لصحّة القيم كما في C:

  • العدد 0 خطأ.
  • وأي عدد آخر صحيح.

ولأن AWK لغة لمعالجة النصوص، فإن قيم الصحّة تمتد لتشمل السلاسل النصية.

  • السلسلة النصية الفارغة "" خطأ.
  • وأي سلسلة نصية غير فارغة صحيحة.
Note

يستخدم AWK المفهوم نفسه لصحّة القيم كما في C

ظهر AWK في مختبرات بيل في سبعينيات القرن العشرين، في البيئة نفسها التي اختُرعت فيها لغة C. وكان للغة C تأثير كبير على صياغة AWK.

Caution

من الغرائب التي ينبغي الانتباه إليها

  • العدد 0 خطأ.
  • أما السلسلة النصية غير الفارغة "0" فهي صحيحة!

وسنتناول أنواع البيانات في AWK بمزيد من التفصيل في مفاهيم لاحقة.

التعليقات

تبدأ التعليقات بالمحرف # وتمتد إلى نهاية السطر.

كيفية تمرير الإدخال إلى awk

يستطيع awk قراءة الإدخال من ملفات أو من الإدخال القياسي. وأي من هذه الطرق سيعمل.

awk '/regex/ {print $1}' file1 file2 ...

awk '/regex/ {print $1}' < file

some_command_here | awk '/regex/ {print $1}'

أمثلة

في الأنظمة الشبيهة بـ Unix، يحتوي /etc/passwd على معلومات عن المستخدمين. ويوصف كل مستخدم في سطر مستقل، وتفصل بين الحقول نقطتان رأسيتان.

ولسرد أسماء المستخدمين:

awk '
    BEGIN { FS = ":" }
    { print $1 }
' /etc/passwd

لاحظ أن الإجراء {print $1} لا نمط له، لذلك يُنفَّذ مع كل سجل.

إذا أردنا قصر الإخراج على المستخدمين الذين يستخدمون bash كصدفة تسجيل دخول، يمكننا كتابة:

awk '
    BEGIN { FS = ":" }
    $7 == "/bin/bash" { print $1 }
' /etc/passwd

المزيد من الأمثلة

إليك بعض برامج awk التي تُنتج النتائج نفسها التي تُنتجها أوامر Unix شائعة أخرى.

  • عرض محتوى ملف

    cat file.txt
    
    awk '1' file.txt
    
  • البحث عن أنماط في ملف

    grep 'foo.*bar' file.txt
    
    awk '/foo.*bar/' file.txt
    
  • عرض بضعة أسطر فقط من بداية ملف

    head -n 20 file.txt
    
    awk '
        1
        NR == 20 {exit}
    ' file.txt
    
  • استبدال نص في ملف

    sed 's/foo/bar/' file.txt
    
    awk '{sub(/foo/, "bar")};1' file.txt
    # or more readably
    awk '
        {
            sub(/foo/, "bar")
            print
        }
    ' file.txt
    
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة

تعلّم المبادئ الأساسية