0Pricing
DevOps Bootcamp · درس

التجميع باستخدام مصفوفات awk والتصنيف

احسب المجاميع والتعدادات وملخّصات التجميع حسب الحقول باستخدام المصفوفات الترابطية المفهرسة بقيم الحقول

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

ما المصفوفات الترابطية في awk؟

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

  • يُصرَّح عنها ضمنيًا: ما عليك سوى إسناد قيمة مثل arr[key] = value
  • المفاتيح سلاسل نصية افتراضيًا (وتُحوَّل الأرقام إلى سلاسل نصية)
  • لا يوجد حد للحجم — إذ تكبّر awk المصفوفة عند الحاجة
  • مثالية لحساب المجاميع والتعدادات والتجميعات حسب المجموعات في مرور واحد

لا تحتاج إلى تهيئة المفتاح قبل زيادته — إذ تتعامل awk تلقائيًا مع المفتاح غير المعين على أنه صفر أو سلسلة نصية فارغة.

عدّ الأسطر لكل مجموعة

أكثر أنماط التجميع شيوعًا هو عدّ عدد مرات ظهور كل قيمة فريدة في حقل. استخدم الحقل $1 (أو أي حقل آخر) مفتاحًا للمصفوفة، وزِد العداد في كل صف مطابق.

تُنفَّذ كتلة END بعد استهلاك جميع المدخلات — وهناك تطبع النتائج المتراكمة.

count[$1]++

بعد المعالجة، تحتوي count على العدد الإجمالي للأسطر لكل قيمة فريدة في $1.

#!/usr/bin/env bash
# Count how many log entries exist per HTTP status code
# Input format: <ip> <date> <method> <path> <status> <bytes>
printf '10.0.0.1 2024-01-01 GET /index 200 512
10.0.0.2 2024-01-01 POST /api 404 128
10.0.0.3 2024-01-01 GET /img 200 2048
10.0.0.4 2024-01-01 GET /api 500 64
10.0.0.5 2024-01-01 DELETE /api 404 32
' | awk '
{
    count[$5]++
}
END {
    for (status in count)
        print status, count[status]
}'

جمع حقل رقمي لكل مجموعة

العدّ ليس سوى أحد أشكال التجميع. ولجمع حقل رقمي حسب حقل آخر، راكم القيمة الرقمية في مصفوفة يكون مفتاحها هو حقل المجموعة.

النمط هو:

  • المفتاح = حقل التجميع (مثلًا، $1 لاسم المستخدم)
  • القيمة = الإجمالي المتراكم للحقل الرقمي (مثلًا، $2 لعدد البايتات)

يحسب هذا مجموع كل مجموعة في مرور واحد عبر awk — من دون الحاجة إلى الفرز أو المعالجة المسبقة.

#!/usr/bin/env bash
# Sum bytes transferred per user from an access log
printf 'alice 1024
bob 512
alice 2048
charlie 256
bob 768
alice 128
' | awk '
{
    bytes[$1] += $2
}
END {
    for (user in bytes)
        printf "%-10s %d bytes\n", user, bytes[user]
}'

دمج العدّ والجمع في مرور واحد

تتيح لك awk إدارة مصفوفات متعددة في الوقت نفسه، ما يوفر العدد والمجموع (وبالتالي المتوسط) لكل مجموعة في عملية مسح واحدة للملف. وهذا أكثر كفاءة بكثير من تشغيل المسار مرتين.

  • count[key]++ — يتتبع مرات الظهور
  • total[key] += $N — يتتبع المجموع المتراكم
  • في END، اقسم total[k] / count[k] لحساب متوسط كل مجموعة
#!/usr/bin/env bash
# Compute per-department headcount and average salary
printf 'Engineering Alice 95000
Engineering Bob 88000
Marketing Carol 72000
Marketing Dave 68000
Engineering Eve 102000
Marketing Frank 75000
' | awk '
{
    dept  = $1
    sal   = $3
    count[dept]++
    total[dept] += sal
}
END {
    printf "%-15s %5s %10s\n", "Department", "Count", "Avg Salary"
    for (d in count)
        printf "%-15s %5d %10.0f\n", d, count[d], total[d]/count[d]
}'

مفاتيح متعددة الحقول للتجميع ثنائي الأبعاد

يمكنك إنشاء مفتاح مركب بضم عدة حقول باستخدام فاصل. ويوفر ذلك تجميعًا ثنائي الأبعاد من دون أي صياغة خاصة.

اختر فاصلًا لا يمكن أن يظهر في البيانات (مثل SUBSEP، وهو فاصل السجلات المضمّن في awk وقيمته \034، أو الرمز الحرفي |).

  • المفتاح المركب: arr[$1 SUBSEP $2] أو arr[$1"|"$2]
  • قسّم المفتاح مجددًا عند الطباعة: split(key, parts, "|")
#!/usr/bin/env bash
# Count requests grouped by HTTP method AND status code
printf 'GET 200
POST 201
GET 404
GET 200
DELETE 204
POST 201
GET 404
POST 500
' | awk '
{
    key = $1 "|" $2
    count[key]++
}
END {
    printf "%-8s %-6s %s\n", "Method", "Status", "Count"
    for (k in count) {
        split(k, parts, "|")
        printf "%-8s %-6s %d\n", parts[1], parts[2], count[k]
    }
}'

تتبّع الحدين الأدنى والأقصى لكل مجموعة

تسهّل المصفوفات الترابطية تتبّع قيمتي min وmax لكل مجموعة. وتكمن الحيلة في التهيئة عند أول ظهور لكل مفتاح فقط، باستخدام الشرط الخاص !(key in arr).

  • تكون !(key in min_arr) صحيحة عند رؤية المفتاح للمرة الأولى
  • بعد التهيئة، قارن القيمة واستبدلها باستخدام فحص أصغر من / أكبر من المعتاد

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

#!/usr/bin/env bash
# Find min and max response time per endpoint
printf '/api/users 120
/api/orders 340
/api/users 98
/api/orders 512
/api/users 210
/api/orders 280
/health 5
/health 7
' | awk '
{
    ep  = $1
    rt  = $2
    if (!(ep in mn)) { mn[ep] = rt; mx[ep] = rt }
    if (rt < mn[ep]) mn[ep] = rt
    if (rt > mx[ep]) mx[ep] = rt
}
END {
    printf "%-15s %6s %6s\n", "Endpoint", "Min", "Max"
    for (ep in mn)
        printf "%-15s %6d %6d\n", ep, mn[ep], mx[ep]
}'

توزيع التكرارات — أعلى N من المجموعات

من المهام الشائعة في الواقع العثور على أكثر القيم تكرارًا ضمن أعلى N. تتولى awk عملية العدّ؛ ثم مرّر النتائج عبر sort وhead لترتيبها واقتطاعها.

يُعد هذا النمط من أنماط المسارات اصطلاحيًا في هندسة الصدفة:

  1. تعدّ awk مرات الظهور في مصفوفة، ثم تطبع count key في END
  2. ترتّب sort -rn عدديًا ترتيبًا تنازليًا
  3. تحتفظ head -n 5 بأعلى 5 نتائج فقط

إن إبقاء awk مركّزة على التجميع وتفويض الفرز إلى sort ينسجم مع فلسفة Unix.

#!/usr/bin/env bash
# Top 3 most active IP addresses from an access log
printf '192.168.1.10 GET /index
10.0.0.5 POST /api
192.168.1.10 GET /css
172.16.0.3 GET /index
10.0.0.5 GET /api
192.168.1.10 DELETE /api
172.16.0.3 POST /login
10.0.0.5 GET /index
10.0.0.5 POST /logout
' | awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' \
  | sort -rn \
  | head -n 3

استخدام NR وFNR للتجميع عبر ملفات متعددة

عند معالجة ملفات متعددة، تتيح لك NR (إجمالي السجلات المقروءة) وFNR (السجلات في الملف الحالي) المضمّنتان في awk تحديد الملف الذي جاء منه كل سجل باستخدام FILENAME.

  • FILENAME — اسم الملف الذي تجري قراءته حاليًا
  • FNR == 1 — يُفعَّل عند بداية كل ملف جديد (وهو مفيد لتخطي العناوين)

يسمح ذلك بإجراء تجميع حسب المجموعات لكل ملف عبر مجلد كامل من السجلات، باستخدام استدعاء واحد لـ awk.

طباعة مخرجات مرتبة من مصفوفات awk

لا تضمن حلقة for (key in array) في awk أي ترتيب. وللحصول على مخرجات حتمية، مرّر طباعة END في awk إلى sort، أو اجمع القيم وفرزها داخل awk باستخدام الدالتين asorti / asort (في GNU awk فقط).

عادةً ما يُفضَّل أسلوب مسار الصدفة المحمول بين الأنظمة:

  • sort -k1,1 — الفرز حسب الحقل الأول (مفتاح المجموعة) أبجديًا
  • sort -k2,2rn — الفرز حسب الحقل الثاني (العدد/المجموع) عدديًا ترتيبًا تنازليًا
#!/usr/bin/env bash
# Bytes per user, sorted alphabetically by username
printf 'zara 800
alice 1500
bob 300
alice 200
zara 400
bob 1100
' | awk '
{
    total[$1] += $2
}
END {
    for (u in total)
        print u, total[u]
}' | sort -k1,1

حذف مفاتيح المصفوفة ومسح الحالة

قد تحتاج أحيانًا إلى إعادة ضبط حالة التجميع أثناء تدفق البيانات — مثلًا عند معالجة ملفات سجلات تفصل بين كل قسم وآخر سطر فارغ أو قيمة مميِّزة.

  • delete arr[key] — يزيل إدخالًا واحدًا
  • delete arr — يمسح المصفوفة بأكملها (في GNU awk)
  • تحقق من وجود المفتاح باستخدام (key in arr) قبل الوصول إليه لتجنب إنشاء إدخالات وهمية

تتيح هذه التقنية إجراء تجميع نافذة منزلقة أو تجميع لكل قسم دون إعادة تشغيل awk.

#!/usr/bin/env bash
# Sum values within each section delimited by "---"
printf 'alice 100
bob 200
---
alice 50
bob 75
charlie 300
---
' | awk '
/^---/ {
    print "-- Section totals --"
    for (u in total) printf "  %-10s %d\n", u, total[u]
    delete total
    next
}
{
    total[$1] += $2
}'

مسار واقعي: تلخيص سجلات Nginx

بعد جمع هذه التقنيات معًا، إليك تجميعًا بجودة مناسبة لبيئات الإنتاج باستخدام awk وفي مرور واحد، على تنسيق السجل الموحّد لـ Nginx. يحسب هذا التجميع عدد الطلبات وإجمالي البايتات ومعدل الأخطاء لكل مضيف افتراضي في عملية مسح واحدة.

التقنيات الأساسية المستخدمة:

  • مفتاح مركب: استخراج vhost من أحد الحقول
  • مصفوفات متوازية: reqs[] وbytes[] وerrors[]
  • تجميع شرطي: $9 >= 400 لعدّ استجابات الأخطاء فقط
  • جدول منسّق باستخدام printf في END
#!/usr/bin/env bash
# Simulated Nginx combined log: host ip - - [date] "METHOD /path HTTP/1.1" status bytes
printf 'api.example.com 10.0.0.1 - - [01/Jan/2024] "GET /v1" 200 1024
www.example.com 10.0.0.2 - - [01/Jan/2024] "GET /" 200 4096
api.example.com 10.0.0.3 - - [01/Jan/2024] "POST /v1" 500 128
www.example.com 10.0.0.4 - - [01/Jan/2024] "GET /img" 404 64
api.example.com 10.0.0.5 - - [01/Jan/2024] "GET /v1" 200 2048
www.example.com 10.0.0.6 - - [01/Jan/2024] "GET /" 200 4096
api.example.com 10.0.0.7 - - [01/Jan/2024] "DELETE /v1" 403 32
' | awk '
{
    host = $1; status = $9; b = $10
    reqs[host]++
    bytes[host] += b
    if (status + 0 >= 400) errors[host]++
}
END {
    printf "%-20s %6s %10s %6s\n", "Host", "Reqs", "Bytes", "Errors"
    for (h in reqs)
        printf "%-20s %6d %10d %6d\n", h, reqs[h], bytes[h], errors[h]+0
}'

اختبار المعرفة: تهيئة الحد الأدنى بطريقة صحيحة

اختبر فهمك لمشكلة شائعة في تجميع awk.

مراجعة الدرس: التجميع باستخدام مصفوفات awk

لقد تعلمت الأنماط الأساسية لحساب التجميعات حسب المجموعات بالكامل داخل awk:

  • العدّ: count[$key]++ — الزيادة مع كل صف، ثم الطباعة في END
  • الجمع: total[$key] += $N — تجميع الحقول الرقمية لكل مجموعة
  • المتوسط: الاحتفاظ بكل من count[] وtotal[]، ثم القسمة في END
  • الحد الأدنى/الأقصى: التهيئة عند أول ظهور باستخدام !(key in arr)، ثم المقارنة
  • المفاتيح المركبة: ضم الحقول باستخدام فاصل لإجراء تجميع متعدد الأبعاد
  • المخرجات المرتبة: تمرير طباعة END في awk إلى sort للحصول على ترتيب حتمي
  • إعادة ضبط الأقسام: استخدام delete arr لمسح الحالة بين الأقسام المنطقية للمدخلات

تتيح لك هذه الأنماط استبدال استعلامات قواعد البيانات الثقيلة أو عمليات المسار المتعددة باستدعاء واحد وفعّال لـ awk — وهي مهارة أساسية في هندسة الصدفة لبيئات الإنتاج.

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

هل درس «التجميع باستخدام مصفوفات awk والتصنيف» مجاني؟

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

ماذا ستتعلم في «التجميع باستخدام مصفوفات awk والتصنيف»؟

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

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

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

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

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

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

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

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

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