0Pricing
DevOps Bootcamp · درس

السجلات والحقول والفواصل المخصّصة في awk

تحكّم في فواصل حقول الإدخال والإخراج لتقسيم أسطر CSV وTSV والسجلات إلى أعمدة مرتّبة

السجلات والحقول والفواصل المخصّصة في awk درس مجاني في DevOps Bootcamp على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في DevOps Bootcamp، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة DevOps Bootcamp 4 دروس في المجموع.

ما السجلات والحقول في awk؟

يقرأ awk الإدخال سطرًا سطرًا. يُسمى كل سطر سجلًا، وتُسمى كل قطعة مفصولة بمسافات بيضاء داخل ذلك السطر حقلًا.

  • $0 — السجل الحالي بأكمله (السطر الكامل)
  • $1 — الحقل الأول
  • $2 — الحقل الثاني
  • $NF — الحقل الأخير (NF = عدد الحقول)

يقسم awk الحقول افتراضيًا عند أي تتابع من المسافات البيضاء (المسافات أو علامات الجدولة). وهذا يجعله مفيدًا مباشرةً لتحليل السجلات ومخرجات الأوامر والبيانات المفصولة بالمسافات.

#!/usr/bin/env bash
# Show how awk sees records and fields
echo 'alice 30 engineer' | awk '{ print "Name:", $1, "Age:", $2, "Role:", $3 }'

# $NF is always the last field — regardless of how many there are
echo 'one two three four five' | awk '{ print "Last field:", $NF }'

فاصل حقول الإدخال: FS

يحدد المتغير المدمج FS (فاصل الحقول) كيفية تقسيم awk لكل سجل إلى حقول. وقيمته الافتراضية هي مسافة واحدة، مما يفعّل وضع التقسيم عند المسافات البيضاء.

يمكنكم ضبط FS بطريقتين:

  • باستخدام الخيار -F في سطر الأوامر: awk -F':'
  • داخل كتلة BEGIN: BEGIN { FS = ":" }

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

#!/usr/bin/env bash
# Parse /etc/passwd using ':' as the field separator
# Field 1 = username, field 3 = UID, field 7 = shell
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin' \
  | awk -F':' '{ print $1, "UID="$3, "shell="$7 }'

ضبط FS في كتلة BEGIN

بالنسبة إلى النصوص البرمجية الأطول من سطر واحد، يُعد وضع FS داخل كتلة BEGIN ممارسة معيارية. تُنفَّذ كتلة BEGIN قبل أن يقرأ awk أي إدخال، ولذلك يكون الفاصل جاهزًا للسجل الأول.

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

الفواصل الشائعة التي ستصادفونها عمليًا:

  • النقطتان : — /etc/passwd و/etc/shadow
  • علامة الجدولة \t — صادرات TSV ومخرجات المصرّفات
  • الفاصلة , — ملفات CSV (البسيطة، من دون حقول مقتبسة)
  • الخط العمودي | — بعض تنسيقات السجلات ونسخ قواعد البيانات
#!/usr/bin/env bash
# awk script using BEGIN to set FS for TSV input
printf 'alice\t30\tengineer\nbob\t25\tdesigner\ncarol\t35\tmanager\n' \
  | awk 'BEGIN { FS = "\t" } { printf "%-10s age=%-3s role=%s\n", $1, $2, $3 }'

تحليل ملفات CSV باستخدام awk

يُعد CSV (القيم المفصولة بفواصل) أحد أكثر تنسيقات البيانات شيوعًا في هندسة الصدفة. يتيح ضبط FS="," لـ awk التعامل مع الفواصل بوصفها محددات.

تنبيه مهم: لا تتعامل إمكانات CSV المدمجة في awk مع الحقول المقتبسة التي تحتوي على فواصل (مثل "Smith, John"). يعمل ذلك على نحو مثالي مع ملفات CSV البسيطة التي لا تحتوي على فواصل داخل الحقول المقتبسة. أما ملفات CSV المتوافقة مع RFC 4180 والتي تحتوي على حقول مقتبسة، فاستخدموا محلل CSV مناسبًا أو miller/csvkit.

من المهام الشائعة في الواقع استخراج أعمدة محددة وتصفية الصفوف حسب القيمة، وكلتاهما سهلتان جدًا باستخدام awk بعد ضبط FS.

#!/usr/bin/env bash
# Simple CSV: extract name and salary columns, filter salary > 50000
data='name,department,salary
alice,engineering,95000
bob,marketing,48000
carol,engineering,112000
dave,hr,45000'

echo "$data" | awk -F',' '
  NR == 1 { next }          # skip header row
  $3 > 50000 { print $1, "earns", $3 }
'

فواصل الحقول متعددة الأحرف والقائمة على Regex

لا يقتصر FS في awk على محرف واحد، بل يمكن أن يكون تعبيرًا نمطيًا. ويفيد ذلك كثيرًا في تنسيقات السجلات الواقعية التي تفصل الحقولَ محدداتٌ متفاوتة الطول.

أمثلة على فواصل تعبيرات نمطية:

  • FS = "[,;]" — التقسيم عند الفاصلة أو الفاصلة المنقوطة
  • FS = "[ \t]+" — التقسيم عند مسافة واحدة أو أكثر أو علامات جدولة (مثل الوضع الافتراضي، لكن بصورة صريحة)
  • FS = "::" — التقسيم عند نقطتين متتاليتين حرفيتين
  • FS = "\\|" — التقسيم عند محرف الخط العمودي (يجب تخليصه)

عندما يكون FS تعبيرًا نمطيًا، يتعامل معه awk (gawk) باعتباره نمطًا لا سلسلة نصية حرفية.

#!/usr/bin/env bash
# Log lines with mixed delimiters: split on " | " or "::" or ","
# Here we split on one or more spaces or pipe characters
printf '2024-01-15 | ERROR | disk full | /dev/sda1\n2024-01-15 | INFO  | startup ok | main\n' \
  | awk -F' \\| ' '{ printf "date=%-12s level=%-6s msg=%s\n", $1, $2, $3 }'

# Split on multiple possible delimiters using character class
echo 'alpha,beta;gamma,delta;epsilon' \
  | awk -F'[,;]' '{ for(i=1; i<=NF; i++) print i": "$i }'

فاصل حقول الإخراج: OFS

يتحكم OFS (فاصل حقول الإخراج) فيما يضعه awk بين الحقول عند إعادة بناء سجل باستخدام print. وقيمته الافتراضية هي مسافة واحدة.

الفكرة الأساسية: لا يُدرج OFS بين الحقول إلا عند استخدام صياغة الفاصلة في print، أو عند إسناد قيمة إلى حقل فيعيد awk بناء $0. أما إذا وصلتم الحقول بمسافات في الشيفرة المصدرية، فلا يُستخدم OFS.

  • print $1, $2, $3 — تؤدي الفواصل إلى إدراج OFS بين الحقول
  • print $1 " " $2 — مسافة صريحة، مع تجاهل OFS

نمط شائع: قراءة CSV وتحويله وكتابته بصيغة TSV، وذلك بضبط FS="," وOFS="\t".

#!/usr/bin/env bash
# Convert CSV to TSV using FS and OFS
data='alice,30,engineer
bob,25,designer
carol,35,manager'

echo "$data" | awk 'BEGIN { FS=","; OFS="\t" } { print $1, $2, $3 }'

echo '---'

# OFS also applies when you modify a field — awk rebuilds $0 with OFS
echo 'alice,30,engineer' | awk 'BEGIN { FS=","; OFS=" | " } { $1=$1; print $0 }'

إجبار awk على إعادة بناء $0 باستخدام OFS

هناك حيلة دقيقة لكنها مهمة: يؤدي إسناد قيمة إلى أي حقل (حتى إسناد الحقل إلى نفسه، $1=$1) إلى إجبار awk على إعادة بناء $0 عبر وصل جميع الحقول باستخدام OFS.

هذه هي الطريقة الاصطلاحية لإعادة تنسيق محددات السجل من دون طباعة كل حقل يدويًا:

  • اضبطوا FS على محدد الإدخال
  • اضبطوا OFS على محدد الإخراج المطلوب
  • فعّلوا إعادة البناء باستخدام $1=$1
  • اطبعوا $0

يتسع هذا الأسلوب لأي عدد من الحقول، ويتجنب تثبيت $1, $2, $3, ... في الشيفرة.

#!/usr/bin/env bash
# Reformat a pipe-delimited file to comma-separated WITHOUT listing every field
printf 'alice|30|engineer|london\nbob|25|designer|paris\ncarol|35|manager|berlin\n' \
  | awk 'BEGIN { FS="|"; OFS="," } { $1=$1; print $0 }'

# Useful when you don't know how many fields there are:
printf 'a|b|c|d|e|f|g\n1|2|3|4|5|6|7\n' \
  | awk 'BEGIN { FS="|"; OFS="\t" } { $1=$1; print $0 }'

فاصل السجلات: RS

كما يقسم FS الحقول داخل السجل، يحدد RS (فاصل السجلات) ما يفصل السجلات بعضها عن بعض. تكون قيمة RS الافتراضية هي محرف السطر الجديد، ولذلك يعالج awk سطرًا واحدًا في كل مرة.

يتيح تغيير RS معالجة قوية للسجلات متعددة الأسطر:

  • RS="" — وضع الفقرات: تفصل الأسطر الفارغة بين السجلات (ويمكن أن تمتد الحقول عبر عدة أسطر)
  • RS=";" — التقسيم عند الفواصل المنقوطة (مفيد لتفريغات SQL)
  • RS="\n" — تحديد السطر الجديد صراحةً (وهو الإعداد الافتراضي)

في وضع الفقرات (RS="")، يظل FS مستخدمًا لتقسيم الحقول داخل السجل متعدد الأسطر، كما تُعامل الأسطر الجديدة داخل السجل تلقائيًا كفواصل للحقول.

#!/usr/bin/env bash
# Paragraph mode: each blank-line-separated block is one record
# Useful for processing structured text blocks (e.g., stanzas, config sections)
data='Name: Alice
Role: Engineer
City: London

Name: Bob
Role: Designer
City: Paris'

echo "$data" | awk 'BEGIN { RS=""; FS="\n" } {
  print "Record", NR":"
  for (i=1; i<=NF; i++) print "  ", $i
  print ""
}'

فاصل سجلات الإخراج: ORS

تتم طباعة ORS (فاصل سجلات الإخراج) بعد كل عبارة print. وتكون قيمته الافتراضية هي السطر الجديد (\n)، ولهذا تنتقل كل عبارة print إلى سطر جديد.

يتيح تغيير ORS ما يلي:

  • ضم السجلات في سطر واحد: ORS=" "
  • إضافة أسطر فارغة بين سجلات الإخراج: ORS="\n\n"
  • إنشاء تنسيقات إخراج مخصصة، مثل أجزاء JSON أو XML

لاحظ أن printf لا يستخدم ORS — فهو ينطبق فقط على عبارة print المجردة. استخدم printf عندما تحتاج إلى تحكم كامل في التنسيق.

#!/usr/bin/env bash
# Join all matching lines onto one line by setting ORS to a space
printf 'apple\nbanana\ncherry\ndate\n' | awk '{ ORS=" " } { print $0 }'
echo  # final newline

# Add a blank line after every output record for readability
printf 'alice 30 engineer\nbob 25 designer\ncarol 35 manager\n' \
  | awk 'BEGIN { ORS="\n\n" } { print $1, "is a", $3 }'

مثال عملي: تحليل سجلات وصول Apache

تتميز سجلات الوصول إلى Apache/nginx بتنسيق معروف ذي حقول مفصولة بمسافات. وتحتوي بعض الحقول، مثل الطابع الزمني، على مسافات وتكون محاطة بأقواس مربعة أو علامات اقتباس، مما يجعل تقسيم الحقول مباشرةً باستخدام awk أمرًا معقدًا.

يتمثل الأسلوب العملي في استخدام FS بتعبير نمطي يراعي البنية، أو استخراج حقول محددة حسب موضعها مع معرفة التنسيق الدقيق.

تكون حقول تنسيق السجل المدمج تقريبًا كما يلي:

  1. عنوان IP للعميل
  2. Ident (عادةً -)
  3. مستخدم المصادقة (عادةً -)
  4. الطابع الزمني (بين أقواس مربعة، ويُحتسب رمزًا واحدًا)
  5. طريقة الطلب+المسار+البروتوكول (بين علامتي اقتباس)
  6. رمز حالة HTTP
  7. عدد بايتات الاستجابة
#!/usr/bin/env bash
# Parse a simulated Apache Combined Log Format line
# Extract: IP, status code, bytes, and request path
logs='192.168.1.10 - alice [15/Jan/2024:10:23:45 +0000] "GET /api/users HTTP/1.1" 200 1523
10.0.0.5 - - [15/Jan/2024:10:23:46 +0000] "POST /login HTTP/1.1" 401 89
172.16.0.3 - bob [15/Jan/2024:10:23:47 +0000] "GET /dashboard HTTP/1.1" 200 8741'

echo "$logs" | awk '{
  ip     = $1
  status = $9
  bytes  = $10
  # Extract the request path from the quoted string in field 7
  split($7, parts, "/")
  path = "/" parts[2]
  printf "ip=%-15s status=%s bytes=%-6s endpoint=%s\n", ip, status, bytes, path
}'

دمج FS وOFS وRS وORS في مسار معالجة

في هندسة shell العملية، نادرًا ما تستخدم هذه الفواصل منفردة. ومن الأنماط الشائعة في مسارات المعالجة استخدام awk بوصفه محول تنسيق في منتصف المسار، لتحويل تنسيق منظم إلى تنسيق منظم آخر.

أهم النقاط عند دمج الفواصل:

  • اضبط دائمًا FS وOFS معًا داخل BEGIN عند تحويل التنسيقات
  • استخدم $1=$1 لتحفيز إعادة بناء $0 عندما تريد إعادة تنسيق جميع الحقول دون إدراجها واحدًا تلو الآخر
  • غيّر RS فقط عندما تمتد سجلاتك فعليًا عبر عدة أسطر
  • استخدم ORS للتحكم في المسافات بين سجلات الإخراج
  • فضّل printf للتنسيق الدقيق، واستخدم print عندما يكون الإنهاء التلقائي بواسطة ORS مناسبًا
#!/usr/bin/env bash
# Full pipeline: read a colon-delimited file,
# filter rows where field 3 (UID) >= 1000 (real users),
# then output as tab-separated: username, UID, home dir
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
alice:x:1001:1001:Alice:/home/alice:/bin/bash
bob:x:1002:1002:Bob:/home/bob:/bin/zsh
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin' \
  | awk 'BEGIN { FS=":"; OFS="\t" } $3 >= 1000 { print $1, $3, $6 }'

اختبار المعرفة: OFS وإعادة بناء الحقول

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

مراجعة الدرس: السجلات والحقول والفواصل

أصبح لديك الآن تحكم كامل في كيفية قراءة awk للبيانات المنظمة وكتابتها. إليك ملخصًا لمتغيرات الفواصل الأربعة:

  • FS — فاصل حقول الإدخال. يُضبط باستخدام -F أو داخل BEGIN. ويمكن أن يكون محرفًا أو سلسلة أو تعبيرًا نمطيًا. القيمة الافتراضية: المسافات البيضاء.
  • OFS — فاصل حقول الإخراج. يُدرج بين الحقول في استدعاءات print $1, $2 وعندما يعيد awk بناء $0 بعد إسناد قيمة إلى أحد الحقول. القيمة الافتراضية: مسافة واحدة.
  • RS — فاصل سجلات الإدخال. يحدد ما يفصل السجلات (الأسطر). القيمة الافتراضية: السطر الجديد. اضبطه على سلسلة فارغة لتفعيل وضع الفقرات.
  • ORS — فاصل سجلات الإخراج. يُضاف بعد كل print. القيمة الافتراضية: السطر الجديد. غيّره لضم الأسطر أو إضافة مسافات.

أهم نمط يجب تذكره هو: اضبط كلًا من FS وOFS داخل BEGIN، ثم استخدم $1=$1 لإعادة بناء $0 كلما أردت إعادة تنسيق الفواصل عبر جميع الحقول دون تثبيت مواضع الحقول في الشيفرة. يعمل هذا النمط مع الملفات التي تحتوي على أي عدد من الأعمدة، وهو أساس مسارات تحويل التنسيقات المعتمدة على awk.

الأسئلة الشائعة

هل درس «السجلات والحقول والفواصل المخصّصة في awk» مجاني؟

نعم — نص درس «السجلات والحقول والفواصل المخصّصة في awk» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة DevOps Bootcamp، انتقل إلى CoddyKit PRO. تتضمن دورة DevOps Bootcamp 4 دروس في المجموع.

ماذا ستتعلم في «السجلات والحقول والفواصل المخصّصة في awk»؟

تحكّم في فواصل حقول الإدخال والإخراج لتقسيم أسطر CSV وTSV والسجلات إلى أعمدة مرتّبة تتمرن على DevOps Bootcamp مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ DevOps Bootcamp؟

لا تُشترط خبرة سابقة. DevOps Bootcamp على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «السجلات والحقول والفواصل المخصّصة في awk»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس DevOps Bootcamp هذا؟

نعم. كل درس في DevOps Bootcamp يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. السجلات والحقول والفواصل المخصّصة في awk
  2. الأنماط والنطاقات وكتل BEGIN وEND
  3. التجميع باستخدام مصفوفات awk والتصنيف
  4. دوال awk وتنسيق printf وإنشاء التقارير
← العودة إلى DevOps Bootcamp