كيفية استخدام لغة AWK لتلاعب النص في Linux

المقدمة

تتبع أدوات لينكس في كثير من الأحيان فلسفة تصميم يونكس. يُشجع على أن تكون الأدوات صغيرة الحجم، واستخدام ملفات نصية عادية للإدخال والإخراج، والعمل بطريقة م moduler. بفضل هذا التراث، لدينا وظائف معالجة نصوص رائعة باستخدام أدوات مثل sed و awk.

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

الصيغة الأساسية

يتم تضمين أمر awk بشكل افتراضي في جميع أنظمة لينكس الحديثة، لذا لا يلزم تثبيته لبدء استخدامه.

يكون awk الأكثر فائدة عند التعامل مع ملفات نصية مهيأة بطريقة قابلة للتنبؤ. على سبيل المثال، فهو ممتاز في تحليل وتلاعب البيانات الجدولية. يعمل على أساس سطري ويكرر عبر الملف بأكمله.

بشكل افتراضي، يستخدم المسافات البيضاء (الفراغات، والتابات، إلخ) لفصل الحقول. لحسن الحظ، تستخدم العديد من ملفات التكوين على نظامك لينكس هذا الشكل.

التنسيق الأساسي لأمر awk هو:

  1. awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

يمكنك حذف إما جزء البحث أو جزء الإجراء من أي أمر awk. بشكل افتراضي، الإجراء المتخذ إذا لم يتم إعطاء جزء “الإجراء” هو “طباعة”. هذا يطبع ببساطة جميع الأسطر التي تتطابق.

إذا لم يتم إعطاء جزء البحث، awk يقوم بتنفيذ الإجراء المدرج في كل سطر.

إذا تم إعطاء كلاهما، يستخدم awk الجزء الذي يبحث فيه لتحديد ما إذا كان السطر الحالي يعكس النمط، ثم يقوم بتنفيذ الإجراءات على التطابقات.

بأبسط شكل له، يمكنك استخدام awk مثل cat لطباعة جميع الأسطر من ملف نصي إلى الشاشة.

أنشئ ملف favorite_food.txt الذي يعرض أطعمة الأصدقاء المفضلة:

  1. echo "carrot sandy
  2. wasabi luke
  3. sandwich brian
  4. salad ryan
  5. spaghetti jessica" > favorite_food.txt

الآن استخدم أمر awk لطباعة الملف على الشاشة:

  1. awk '{print}' favorite_food.txt

سترى الملف مطبوعًا على الشاشة:

Output
carrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica

هذا ليس مفيدًا جدًا. لنجرب قدرات تصفية البحث في awk عن طريق البحث في الملف عن النص “sand”:

  1. awk '/sand/' favorite_food.txt
Output
carrot sandy sandwich brian

كما ترى، يطبع awk الآن فقط الأسطر التي تحتوي على الأحرف “sand” فيها.

باستخدام التعبيرات العادية، يمكنك استهداف أجزاء محددة من النص. لعرض فقط السطر الذي يبدأ بالحروف “sand”، استخدم التعبير العادي ^sand:

  1. awk '/^sand/' favorite_food.txt

هذه المرة، يتم عرض سطر واحد فقط:

Output
sandwich brian

بالمثل، يمكنك استخدام جزء الإجراء لتحديد الأجزاء التي تريد طباعتها. على سبيل المثال، لطباعة العمود الأول فقط، استخدم الأمر التالي:

  1. awk '/^sand/ {print $1;}' favorite_food.txt
Output
sandwich

يمكنك الإشارة إلى كل عمود (حسب الفواصل البيضاء) باستخدام المتغيرات المرتبطة برقم العمود. على سبيل المثال، العمود الأول هو $1، والثاني هو $2، ويمكنك الإشارة إلى السطر بأكمله باستخدام $0.

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

يستخدم أمر awk بعض المتغيرات الداخلية لتعيين بعض القطع المعلوماتية أثناء معالجة ملف.

المتغيرات الداخلية التي يستخدمها awk هي:

  • FILENAME: تشير إلى ملف الإدخال الحالي.
  • FNR: تشير إلى عدد السجل الحالي بالنسبة لملف الإدخال الحالي. على سبيل المثال، إذا كان لديك ملفين للإدخال، فسيخبرك هذا برقم السجل في كل ملف بدلاً من المجموع.
  • FS: الفاصل المستخدم حاليًا للدلالة على كل حقل في سجل. بشكل افتراضي، يتم تعيين هذا إلى الفواصل البيضاء.
  • NF: عدد الحقول في السجل الحالي.
  • NR: عدد السجل الحالي.
  • OFS: فاصل الحقول للبيانات المخرجة. بشكل افتراضي، يتم تعيين هذا إلى الفواصل البيضاء.
  • ORS: فاصل السجلات للبيانات المخرجة. بشكل افتراضي، يتم تعيين هذا إلى حرف السطر الجديد.
  • RS: الفاصلة السجلية المستخدمة للتمييز بين السجلات المنفصلة في ملف الإدخال. بشكل افتراضي، هذا هو حرف السطر الجديد.

يمكنك تغيير قيم هذه المتغيرات حسب الحاجة في ملفاتك. عادةً ما تفعل ذلك خلال مرحلة التهيئة لعملية المعالجة الخاصة بك.

وهذا يقودنا إلى مفهوم مهم آخر. بناء جملة awk أكثر تعقيدًا قليلاً مما استخدمته حتى الآن. هناك أيضًا كتل BEGIN و END الاختيارية التي يمكن أن تحتوي على أوامر للتنفيذ قبل وبعد معالجة الملف، على التوالي.

هذا يجعل بناء جملتنا الموسعة تبدو على هذا النحو:

  1. awk 'BEGIN { action; }
  2. /search/ { action; }
  3. END { action; }' input_file

كلمات مفتاحية BEGIN و END مجموعات محددة من الشروط، تمامًا مثل معايير البحث. تتطابق قبل وبعد معالجة المستند.

هذا يعني أنه يمكنك تغيير بعض المتغيرات الداخلية في قسم BEGIN. على سبيل المثال، يتم تقسيم ملف /etc/passwd بفواصل (:) بدلاً من المسافات.

لطباعة العمود الأول من هذا الملف، قم بتنفيذ الأمر التالي:

  1. awk 'BEGIN { FS=":"; }
  2. { print $1; }' /etc/passwd
Output
root daemon bin sys sync games man . . .

يمكنك استخدام كتل BEGIN و END لطباعة معلومات حول الحقول التي تقوم بطباعتها. استخدم الأمر التالي لتحويل البيانات من الملف إلى جدول، بتنسيق مرتب بشكل جميل باستخدام الأقواس الأفقية \t:

  1. awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
  2. {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
  3. END { print "---------\nFile Complete" }' /etc/passwd

سترى هذا الإخراج:

Output
User UID GID Home Shell -------------- root 0 0 /root /bin/bash daemon 1 1 /usr/sbin /bin/sh bin 2 2 /bin /bin/sh sys 3 3 /dev /bin/sh sync 4 65534 /bin /bin/sync . . . --------- File Complete

كما يمكنك أن تلاحظ، يمكنك تنسيق الأشياء بشكل لائق باستفادة من بعض ميزات awk.

كل قسم موسع اختياري. في الواقع، القسم الرئيسي للعمل اختياري إذا تم تعريف قسم آخر. على سبيل المثال، يمكنك القيام بأشياء مثل هذا:

  1. awk 'BEGIN { print "We can use awk like the echo command"; }'

وسترى هذا الإخراج:

Output
We can use awk like the echo command

الآن دعونا نلقي نظرة على كيفية البحث عن النص داخل حقول الإخراج.

البحث في الحقول والتعبيرات المركبة

في أحد الأمثلة السابقة، قمت بطباعة السطر في ملف favorite_food.txt الذي بدأ بـ “sand”. كان هذا سهلاً لأنك كنت تبحث عن بداية السطر بأكمله.

ماذا لو أردت معرفة ما إذا كان نمط البحث مطابقًا لبداية الحقل بدلاً من ذلك؟

أنشئ نسخة جديدة من ملف favorite_food.txt يضيف رقم العنصر أمام طعام كل شخص:

  1. echo "1 carrot sandy
  2. 2 wasabi luke
  3. 3 sandwich brian
  4. 4 salad ryan
  5. 5 spaghetti jessica" > favorite_food.txt

إذا كنت تريد العثور على جميع الأطعمة من هذا الملف التي تبدأ بـ “sa”، قد تبدأ بمحاولة شيء مثل هذا:

  1. awk '/sa/' favorite_food.txt

يظهر هذا كل الأسطر التي تحتوي على “sa”:

Output
1 carrot sandy 2 wasabi luke 3 sandwich brian 4 salad ryan

هنا، تتطابق أي حالة من “sa” في الكلمة. ينتهي هذا بتضمين أشياء مثل “wasabi” التي لها النمط في الوسط، أو “sandy” التي ليست في العمود الذي تريده. في هذه الحالة، أنت مهتم فقط بالكلمات التي تبدأ بـ “sa” في البداية في العمود الثاني.

يمكنك إخبار awk بأن يطابق فقط في بداية العمود الثاني باستخدام هذا الأمر:

  1. awk '$2 ~ /^sa/' favorite_food.txt

كما يمكنك أن ترى، يتيح لنا هذا الأمر البحث فقط في بداية العمود الثاني للعثور على تطابق.

الجزء field_num ~ يحدد أن awk يجب أن يولي اهتمامًا فقط للعمود الثاني.

Output
3 sandwich brian 4 salad ryan

يمكنك بسهولة البحث عن الأشياء التي لا تطابق من خلال تضمين الرمز “!” قبل العلامة المائلة (~). سيُرجع هذا الأمر جميع الأسطر التي لا تحتوي على طعام يبدأ بـ “sa”:

  1. awk '$2 !~ /^sa/' favorite_food.txt
Output
1 carrot sandy 2 wasabi luke 5 spaghetti jessica

إذا قررت فيما بعد أنك مهتم فقط بالأسطر التي لا تبدأ بـ “sa” وكان رقم العنصر أقل من 5، يمكنك استخدام تعبير مركب مثل هذا:

  1. awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

يقدم هذا مفهومات جديدة قليلة. الأولى هي القدرة على إضافة متطلبات إضافية لتطابق السطر باستخدام عامل &&. باستخدام هذا، يمكنك دمج عدد لا محدود من الشروط لتطابق السطر. في هذه الحالة، تستخدم هذا العامل لإضافة فحص لقيمة العمود الأول بأن تكون أقل من 5.

سترى هذا الإخراج:

Output
1 carrot sandy 2 wasabi luke

يمكنك استخدام awk لمعالجة الملفات، لكن يمكنك أيضًا العمل مع إخراج البرامج الأخرى.

معالجة الإخراج من البرامج الأخرى

يمكنك استخدام الأمر awk لتحليل إخراج برامج أخرى بدلاً من تحديد اسم الملف. على سبيل المثال، يمكنك استخدام awk لتحليل عنوان IPv4 من أمر ip.

يعرض أمر ip a عنوان IP وعنوان البث، ومعلومات أخرى حول جميع واجهات الشبكة على جهازك. لعرض المعلومات لواجهة تسمى eth0، استخدم هذا الأمر:

  1. ip a s eth0

سترى النتائج التالية:

Output
2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever

يمكنك استخدام awk لاستهداف سطر inet ثم طباعة العنوان IP فقط:

  1. ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

تقول العلامة -F لـ awk أن يفصل بواسطة شرطات مائلة أو مسافات باستخدام التعبير العادي [\/ ]+. هذا يفصل السطر inet 172.17.0.11/16 إلى حقول منفصلة. يكون العنوان IP في الحقل الثالث لأن المسافات في بداية السطر تحتسب أيضًا كحقل، لأنك قمت بتفصيل حسب المسافات بالإضافة إلى الشرطات المائلة. لاحظ أن awk يعامل المسافات المتتالية كمسافة واحدة في هذه الحالة.

يظهر الإخراج العنوان IP:

Output
172.17.0.11

ستجد العديد من الأماكن التي يمكنك استخدام فيها awk للبحث أو تحليل إخراج أوامر أخرى.

الاستنتاج

حاليًا، يجب أن تكون لديك فهم أساسي لكيفية استخدام أمر awk لتلاعب وتنسيق وطباعة الملفات النصية وتيارات النصوص. الـ Awk هو موضوع أكبر بكثير، وهو في الواقع لغة برمجة كاملة تتضمن تعيين المتغيرات وهياكل التحكم والوظائف المدمجة، والمزيد من ذلك. يمكنك استخدامه في النصوص الخاصة بك لتنسيق النص بطريقة موثوقة.

لمعرفة المزيد عن awk، يمكنك قراءة الكتاب العام المجاني الذي كتبه مبتكروه الذي يتناول تفاصيل أكثر.

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-the-awk-language-to-manipulate-text-in-linux