استخدام لغة AWK للتعامل مع النصوص في نظام لينكس: دليل شامل ومفصل
تُعتبر لغة AWK واحدة من أقوى وأشهر أدوات معالجة النصوص في نظام لينكس، حيث تتميز بقدرتها الفريدة على تحليل النصوص، استخراج البيانات، تنفيذ العمليات الحسابية، وإعداد التقارير بشكل ديناميكي وفعّال. نشأت هذه اللغة في سبعينيات القرن الماضي على يد Alfred Aho وPeter Weinberger وBrian Kernighan، وهي تحمل الحروف الأولى من أسمائهم، مما يعكس أهمية AWK في عالم البرمجة النصية.
مقدمة عن لغة AWK
لغة AWK هي لغة برمجة نصية مصممة خصيصًا لمعالجة النصوص بشكل مبسط وسريع، خاصة في ملفات النصوص التي تحتوي على بيانات منظمة بطريقة معينة مثل ملفات CSV أو ملفات السجلات (logs). تعتمد AWK على نمط معالجة يعتمد على قراءة النص سطرًا بسطر، تطبيق مجموعة من القواعد أو التعبيرات (Patterns & Actions) على كل سطر، ومن ثم إخراج النتائج بناءً على هذه القواعد.
تتضمن لغة AWK مجموعة واسعة من الأدوات التي تمكن المستخدم من التعامل مع النصوص بطريقة تشبه قواعد البيانات البسيطة، مما يجعلها أداة مثالية لمعالجة البيانات وتحليلها في البيئات النصية.
أساسيات عمل لغة AWK
تقوم AWK بقراءة ملف نصي أو إدخال قياسي (standard input) سطرًا بسطر. لكل سطر، تقوم بمقارنته مع نمط معين، وعند تطابق النمط، تنفذ الإجراءات المرتبطة به. الصيغة الأساسية لبرنامج AWK هي:
nginxawk 'pattern { action }' filename
-
pattern: هو شرط يتم تطبيقه على كل سطر، مثل البحث عن كلمة معينة أو اختبار رقم في عمود معين.
-
action: هو الكود الذي يُنفذ إذا تحقق الشرط، مثل طباعة الأعمدة المطلوبة أو تعديل البيانات.
في حال عدم وجود نمط محدد، يتم تطبيق الإجراء على كل سطر.
المكونات الأساسية للغة AWK
1. الحقول (Fields)
تقسم AWK كل سطر من النص إلى حقول مفصولة بشكل افتراضي بمسافات أو علامات التبويب. يمكن الوصول إلى هذه الحقول باستخدام المتغيرات المسبقة مثل $1 للحقل الأول، $2 للحقل الثاني، وهكذا. أما المتغير $0 فيمثل السطر الكامل.
مثال على طباعة الحقل الأول والثاني من كل سطر:
bashawk '{ print $1, $2 }' filename
2. الأنماط (Patterns)
يمكن أن تكون الأنماط تعبيرات شرطية، نصوص ثابتة، أو تعبيرات رياضية. مثلاً، لطباعة السطور التي تحتوي على كلمة “error”:
bashawk '/error/ { print $0 }' filename
3. الإجراءات (Actions)
تمثل الأوامر التي يتم تنفيذها إذا تحقق النمط. من هذه الأوامر: الطباعة، التعديل، الجمع، الحساب، وما إلى ذلك.
المتغيرات المدمجة في AWK
توفر AWK مجموعة من المتغيرات التي تستخدم أثناء معالجة النصوص، ومنها:
-
NR: رقم السطر الحالي في الملف.
-
NF: عدد الحقول في السطر الحالي.
-
FS: محدد الحقول (Field Separator) الافتراضي هو المسافة.
-
OFS: محدد الحقول عند الإخراج، افتراضيًا مسافة.
-
RS: محدد السطر، افتراضيًا نهاية السطر.
-
ORS: محدد السطر عند الإخراج، افتراضيًا نهاية السطر.
تُستخدم هذه المتغيرات لتخصيص كيفية قراءة النصوص وكيفية إخراج النتائج.
استخدام AWK في أمثلة عملية
1. استخراج الأعمدة من ملف CSV
لنفترض وجود ملف data.csv يحتوي على بيانات مقسمة بفواصل، ويريد المستخدم استخراج العمود الثالث فقط:
bashawk -F',' '{ print $3 }' data.csv
هنا تم تحديد الفاصل -F',' ليكون الفاصلة، مما يسمح بتقسيم السطر إلى حقول حسب الفواصل.
2. حساب مجموع أرقام في عمود معين
مثلاً حساب مجموع الأرقام في العمود الثاني من ملف نصي:
bashawk '{ sum += $2 } END { print sum }' filename
هذا الأمر يقوم بإضافة قيمة الحقل الثاني لكل سطر إلى المتغير sum، وعند نهاية الملف (END) يطبع مجموع القيم.
3. طباعة الأسطر التي تحقق شرطًا معينًا
طباعة الأسطر التي يكون فيها العدد في العمود الأول أكبر من 100:
bashawk '$1 > 100 { print $0 }' filename
4. تنسيق وإعادة ترتيب الأعمدة
إعادة ترتيب الأعمدة وطباعة الحقل الثالث أولاً ثم الأول:
bashawk '{ print $3, $1 }' filename
التعامل مع النصوص المعقدة باستخدام AWK
لغة AWK ليست فقط للأوامر البسيطة بل تتوسع لتشمل التعامل مع النصوص المعقدة من خلال:
-
الوظائف المدمجة: مثل
length(),substr(),index(),split()وغيرها. -
الحلقات: مثل
for,whileلتكرار عمليات على النصوص أو الحقول. -
الشروط:
if,elseلاتخاذ قرارات بناءً على محتوى السطر. -
المصفوفات: لتخزين القيم المؤقتة أو تجميع البيانات.
مثال: استخدام دالة substr لاستخراج جزء من النص
إذا كان لدينا عمود يحتوي على نص طويل ونريد استخراج أول 5 حروف فقط:
bashawk '{ print substr($1, 1, 5) }' filename
مثال: حساب تكرار الكلمات
يمكن باستخدام المصفوفات حساب عدد مرات ظهور كلمة معينة في ملف نصي:
bashawk '{ count[$1]++ } END { for (word in count) print word, count[word] }' filename
هنا، يتم استخدام المصفوفة count لتخزين عدد مرات ظهور كل كلمة في الحقل الأول، ويتم طباعتها بعد انتهاء القراءة.
تخصيص محدد الحقول (FS) ومحدد الإخراج (OFS)
تتيح AWK تغيير الفاصل الذي يستخدم لتقسيم النص إلى حقول، بالإضافة إلى تخصيص فاصل الحقول في الإخراج، مما يجعلها مرنة جدًا في التعامل مع ملفات ذات تنسيقات مختلفة.
مثلاً إذا كان الفاصل هو علامة نقطتين (:) بدلاً من المسافة:
bashawk -F':' '{ print $1, $3 }' filename
ولتغيير فاصل الإخراج إلى فاصلة:
bashawk 'BEGIN { OFS="," } { print $1, $2 }' filename
استخدام AWK مع أدوات لينكس الأخرى
يمكن دمج AWK بسلاسة مع أدوات أخرى مثل grep, sed, sort، وغيرها لتكوين أوامر معالجة نصوص متقدمة.
مثلاً، استخراج الأسطر التي تحتوي على كلمة معينة، ثم ترتيبها:
bashgrep "error" logfile.txt | awk '{ print $2, $5 }' | sort
إنشاء برامج نصية باستخدام AWK
يمكن حفظ أوامر AWK في ملف نصي وجعلها برامج نصية مستقلة تعمل بشكل مباشر، مما يسهل إعادة الاستخدام والبرمجة المتقدمة.
مثال لبرنامج نصي بسيط:
awk#!/usr/bin/awk -f # برنامج لعرض الأعمدة الأولى والثانية فقط { print $1, $2 }
بعد حفظ الملف، يمكن جعله قابلًا للتنفيذ بواسطة:
bashchmod +x script.awk
./script.awk filename
مزايا استخدام AWK في معالجة النصوص
-
سرعة الأداء: تعمل AWK بسرعة عالية على معالجة الملفات النصية الكبيرة.
-
المرونة: تناسب مهام متعددة من استخراج البيانات، التحليل، إعادة التنسيق.
-
سهولة التعلم: بنية بسيطة وسلسة تتيح للمستخدمين البدء بسرعة.
-
التكامل مع بيئة لينكس: تعمل بشكل متكامل مع باقي الأدوات مما يعزز قدراتها.
-
قوة التعبيرات النمطية: دعم قوي للـ regex مما يمكن من عمليات بحث متقدمة.
جدول مقارنة بين AWK وأدوات معالجة النصوص الأخرى في لينكس
| الأداة | الاستخدام الرئيسي | نقاط القوة | نقاط الضعف |
|---|---|---|---|
| AWK | معالجة نصوص معقدة وتحليل البيانات | مرونة عالية، دعم الحسابات، مدمج في لينكس | أداء أقل في النصوص غير المنظمة جداً |
| sed | تعديل النصوص بخطوط أو أنماط محددة | سريع، مناسب للتعديلات النصية البسيطة | صعوبة التعامل مع البيانات المعقدة |
| grep | البحث عن أنماط نصية في الملفات | سريع وفعال في البحث عن الأنماط | غير مناسب للتحليل أو التعديل |
| cut | استخراج أعمدة أو حقول من النصوص | بسيط وسهل الاستخدام | محدود في التعديلات أو المعالجة |
نصائح متقدمة لاستخدام AWK بكفاءة
-
الاستفادة من القسم
BEGINوEND: يمكن تنفيذ أوامر قبل بدء قراءة الملف وبعد الانتهاء منه، مثل تهيئة المتغيرات أو طباعة النتائج النهائية.مثال:
bashawk 'BEGIN { print "Start Processing" } { print $1 } END { print "End Processing" }' filename -
استخدام التعبيرات النمطية لتحسين البحث: يمكن استغلال regex قوية لتحديد الأنماط بدقة.
-
تجميع وتحليل البيانات باستخدام المصفوفات: تخزين البيانات مؤقتًا يسمح بتحليل أعمق كالعد، التجميع، والتصفية.
-
تقسيم المهام المعقدة إلى خطوات صغيرة: كتابة سكربتات AWK متعددة تمر عبر مراحل، يسهل الصيانة والتطوير.
حالات استخدام متقدمة لـ AWK
-
تحليل ملفات السجلات (Logs): يمكن استخراج الحقول المهمة، حساب الإحصائيات، وإنشاء تقارير تلقائية.
-
تصفية البيانات المالية: جمع القيم، حساب المتوسطات، وتحديد القيم القصوى أو الدنيا.
-
تحويل تنسيقات الملفات: مثل تحويل CSV إلى TSV أو العكس.
-
إنشاء تقارير نصية ديناميكية: تجميع البيانات وعرضها في شكل منسق مع رؤوس وأعمدة.
الخلاصة
تُعد لغة AWK أداة لا غنى عنها لكل من يتعامل مع النصوص والبيانات في بيئة لينكس، حيث تجمع بين البساطة والقدرة على تنفيذ مهام معقدة بكفاءة عالية. من خلال إتقان أساسيات AWK والتوسع في استخدام ميزاتها المتقدمة، يمكن للمستخدمين تحويل مهام معالجة النصوص التي تبدو معقدة إلى عمليات سهلة وسريعة.
المرونة التي تقدمها AWK في التعامل مع النصوص، دعم التعبيرات النمطية، إمكانية استخدام المتغيرات، الحلقات، والدوال المدمجة، تجعلها الخيار الأمثل للمطورين والمحللين على حد سواء، سواء في بيئة العمل اليومية أو في مشروعات تحليل البيانات الضخمة.
المراجع
-
“The AWK Programming Language,” Alfred V. Aho, Brian W. Kernighan, and Peter J. Weinberger, Addison-Wesley, 1988.
-
GNU Awk User’s Guide: https://www.gnu.org/software/gawk/manual/gawk.html

