Linux: الفرسان الثلاثة لمعالجة النصوص — awk / sed / cut

إذا grep لـ"البحث"، فإن awk وsed وcut لـ"التغيير". cut يقطع الأعمدة، وawk يولّد تقارير بيانات، وsed يقوم بالاستبدال المجمّع — مع الأنابيب، يمكنها التعامل مع تقريبًا أي مهمة نصية.

📋 المتطلبات المسبقة: يجب إكمال

1. ما ستتعلمه


2. قصة معالجة ملف CSV

(1) نقطة الألم: ملف CSV يحتاج تحويل صياغة

تلقى شياو مينغ ملف CSV واحتاج استخراج العمودين 2 و5، وإزالة الأسطر الفارغة، وتغيير المحدد من فواصل إلى علامات جدولة.

(2) سلسلة أنبوب واحد تفعل كل شيء

BASH
cat data.csv | cut -d',' -f2,5 | sed '/^$/d' | tr ',' '\t' > output.tsv

(3) الفائدة: معالجة بيانات بدون برمجة

تخطى شياو مينغ عناء فتح Excel أو كتابة سكريبت Python. أمر واحد، ومعالجة البيانات تمت.


3. نقاط المعرفة

(1) cut — تقطيع بالأعمدة

BASH
# تقسيم بمحدد
cut -d',' -f1,3 file.csv    # محدد فاصلة، أخذ العمودين 1 و3
cut -d: -f1 /etc/passwd     # محدد نقطتان، أخذ أسماء المستخدمين

> ℹ️ ملاحظة: `cut` مناسب لاستخراج أعمدة بسيط (محدد ثابت، أرقام أعمدة ثابتة). للسيناريوهات التي تتطلب تصفية شرطية أو حسابات أو تنسيقًا، استخدم `awk` بدلًا من ذلك. مثلًا، `awk -F: '$3 >= 1000 {print $1}' /etc/passwd` يمكنه تصفية المستخدمين ذوي UID ≥ 1000 — `cut` لا يستطيع ذلك.

# تقسيم بموضع المحرف
cut -c1-5 file.txt          # أخذ المحارف 1-5
cut -c1,3,5 file.txt        # أخذ المحارف 1 و3 و5

(2) awk — مولّد تقارير البيانات

awk لغة معالجة نصوص كاملة. نمطه الأساسي:

BASH
awk 'pattern {action}' file

متغيرات awk المدمجة:

المتغير المعنى
$0 السطر بالكامل
$1 الحقل الأول
$2 الحقل الثاني
NF عدد الحقول
NR رقم السطر
FS فاصل حقول الإدخال (افتراضي: مسافة/جدولة)
OFS فاصل حقول الإخراج (افتراضي: مسافة)
💡 نصيحة: احفظ المتغيرات الأساسية لـawk — $0 هو السطر كاملًا، و$1/$2/$3 هي الحقول 1/2/3، وNR رقم السطر، وNF عدد الحقول ($NF هو الحقل الأخير). مع -F: لتحديد محدد، يمكنك التعامل مع معظم مهام استخراج النصوص.

BASH
# استخدام أساسي
awk '{print $1}' file.txt           # طباعة العمود 1
awk '{print $1, $3}' file.txt       # طباعة العمودين 1 و3
awk '{print NR, $0}' file.txt       # طباعة رقم السطر والسطر كاملًا
awk '{print $NF}' file.txt           # طباعة العمود الأخير
awk -F: '{print $1}' /etc/passwd    # تحديد النقطتين كمحدد

# مطابقة الأنماط
awk '/error/ {print}' log.txt       # معالجة الأسطر التي تحتوي error فقط
awk '$3 > 100 {print $1, $3}' data.txt  # إخراج فقط عندما العمود 3 > 100

# تجميع
awk '{sum += $1} END {print sum}' numbers.txt  # مجموع
awk '{count++} END {print count}' file.txt     # عدّ

(3) sed — المحرر الانسيابي

BASH
# استبدال
sed 's/old/new/' file.txt          # استبدال أول ظهور في كل سطر
sed 's/old/new/g' file.txt         # استبدال شامل
sed 's/old/new/2' file.txt         # استبدال الظهور الثاني فقط في كل سطر
sed 's/old/new/g' file.txt > new.txt  # إخراج لملف جديد
sed -i 's/old/new/g' file.txt     # تعديل في المكان (يعدّل الملف مباشرة)
sed -i.bak 's/old/new/g' file.txt # نسخ احتياطي للأصل كـfile.txt.bak

> 💡 نصيحة: `sed -i` يعدّل الملف في مكانه بدون إمكانية التراجع. عاين النتيجة أولًا بدون `-i`: `sed 's/old/new/g' file.txt`، ثم أضف `-i` بعد التأكيد. أو استخدم `sed -i.bak` لإنشاء نسخة احتياطية تلقائيًا.

# حذف
sed '/pattern/d' file.txt          # حذف أسطر تطابق النمط
sed '3d' file.txt                  # حذف السطر 3
sed '5,10d' file.txt               # حذف الأسطر 5-10
sed '/^$/d' file.txt               # حذف الأسطر الفارغة

# طباعة
sed -n '5,10p' file.txt            # طباعة الأسطر 5-10 فقط
sed -n '/pattern/p' file.txt       # طباعة الأسطر المطابقة فقط

(4) tr — ترجمة المحارف

BASH
# تحويل حالة الأحرف
echo "hello" | tr 'a-z' 'A-Z'      # HELLO
cat file.txt | tr '[:lower:]' '[:upper:]'

# استبدال وحذف
echo "a,b,c" | tr ',' ' '          # a b c
echo "hello   world" | tr -s ' '   # hello world (ضغط المسافات المتكررة)
echo "hello123" | tr -d '0-9'      # hello (حذف الأرقام)
echo "abc123" | tr -d '[:digit:]'  # abc (حذف الأرقام)

# تحويل نهايات الأسطر (ويندوز ↔ يونكس)
tr -d '\r' < win.txt > unix.txt    # إزالة CR الخاص بويندوز
tr '\n' ',' < list.txt             # استبدال الأسطر الجديدة بفواصل

(5) diff — مقارنة الملفات

TEXT
diff file1.txt file2.txt           # مقارنة أساسية
diff -u file1.txt file2.txt        # صياغة موحدة (أكثر قابلية للقراءة)
diff -i file1.txt file2.txt        # تجاهل حالة الأحرف
diff -w file1.txt file2.txt        # تجاهل اختلافات المسافات
diff -r dir1/ dir2/                # مقارنة تكرارية للدلائل

(6) ▶ مثال: تقطيع أعمدة بـcut

BASH
# استخراج اسم المستخدم وصدفة الولوج من /etc/passwd
cut -d: -f1,7 /etc/passwd | head -5
# root:/bin/bash
# daemon:/usr/sbin/nologin
# bin:/usr/sbin/nologin

# أخذ العمود 5 (حجم الملف) من مخرجات ls -l
ls -la | tr -s ' ' | cut -d' ' -f5 | head -5

الإخراج:

TEXT
root:/bin/bash
daemon:/usr/sbin/nologin
bin:/usr/sbin/nologin
sys:/usr/sbin/nologin
sync:/usr/sbin/nologin
4096
4096
1234
5678
910

(7) ▶ مثال: معالجة أعمدة بـawk

BASH
# طباعة اسم المستخدم والدليل المنزلي
awk -F: '{print $1, "Home:", $6}' /etc/passwd | head -5

# إيجاد مستخدمين عاديين بUID أكبر من 1000
awk -F: '$3 >= 1000 {print $1, "(UID:" $3 ")"}' /etc/passwd

# حساب إجمالي حجم الملفات
ls -la | grep "^-" | awk '{sum += $5} END {print "Total:", sum/1024/1024, "MB"}'

# إخراج منسّق (printf)
ls -la | awk '{printf "%-20s %8s\n", $9, $5}'

الإخراج:

TEXT
root Home: /root
daemon Home: /usr/sbin
bin Home: /bin
sys Home: /dev
nobody Home: /nonexistent
alice (UID:1000)
bob (UID:1001)
Total: 256.5 MB
.bashrc                 3771
.profile                220
.bash_history           1234

(8) ▶ مثال: استبدال مجموع بـsed

BASH
# استبدال localhost بـ127.0.0.1 في الملف
sed -i 's/localhost/127.0.0.1/g' config.txt

# تعليق الأسطر التي تبدأ بـlisten في ملف الإعدادات
sed -i '/^listen/s/^/#/' nginx.conf

# إدراج سطر جديد بعد السطر 2
sed '2a\New line inserted' file.txt

# استخراج الطوابع الزمنية من ملف السجل
sed -n 's/.*\[\(.*\)\].*/\1/p' access.log | head -5

الإخراج:

TEXT
07/Jul/2026:10:15:30 +0000
07/Jul/2026:10:15:31 +0000
07/Jul/2026:10:15:32 +0000
07/Jul/2026:10:15:33 +0000
07/Jul/2026:10:15:34 +0000

(9) ▶ مثال: ترجمة محارف بـtr

BASH
# عدّ الكلمات في النص
cat file.txt | tr -s ' ' '\n' | sort | uniq -c | sort -rn | head -10

# تحويل قائمة لسطر واحد مفصول بفواصل
cat list.txt | tr '\n' ',' | sed 's/,$//'

# إزالة كل التعليقات والأسطر الفارغة من ملف إعدادات
grep -v "^#" config.txt | grep -v "^$" | tr -s '\n'

الإخراج:

TEXT
    42 the
    28 and
    25 linux
    20 file
    18 command
    15 user
    12 system
    10 process
     8 directory
     6 shell
apple,banana,cherry,date
ServerName localhost
Listen 80
DocumentRoot /var/www/html
ErrorLog /var/log/apache2/error.log

(10) ▶ مثال: مقارنة ملفات بـdiff

TEXT
# إنشاء نسختين
echo -e "apple\nbanana\norange" > v1.txt
echo -e "apple\nblueberry\norange" > v2.txt

# مقارنة
diff -u v1.txt v2.txt
# --- v1.txt
# +++ v2.txt
# @@ -1,3 +1,3 @@
#  apple
# -banana
# +blueberry
#  orange

(11) ▶ مثال شامل: تقرير مراقبة النظام

BASH
#!/bin/bash
# sys-report.sh - Generate system monitoring report

echo "========================================="
echo "        System Monitoring Report"
echo "        Generated at: $(date)"
echo "========================================="
echo ""

echo "1. Top 5 Processes by CPU Usage"
ps aux --sort=-%cpu | head -6 | awk '{printf "%-10s %-5s %-5s %s\n", $1, $2, $3, $11}'

echo ""
echo "2. Disk Usage"
df -h | grep "^/" | awk '{printf "%-20s %5s %5s %5s\n", $6, $2, $3, $5}'

echo ""
echo "3. Top 5 by Memory Usage"
ps aux --sort=-%mem | head -6 | awk '{printf "%-10s %-5s %-5s %s\n", $1, $2, $4, $11}'

echo ""
echo "4. Error Count in /var/log"
grep -ric "error" /var/log/*.log 2>/dev/null | grep -v ":0" | head -10

echo ""
echo "5. Listening Ports"
ss -tlnp | tail -n +2 | awk '{print $4, $1}' | sed 's/.*://'

echo ""
echo "========================================="

❓ أسئلة شائعة

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

س: هل sed -i محفوف بالمخاطر لتعديل الملف الأصلي؟ ج: نعم — sed -i يعدّل الملف في مكانه بدون إمكانية التراجع. عاين بدون -i أولًا، أو استخدم sed -i.bak لإنشاء نسخة احتياطية تلقائيًا. بعد تأكيد النتيجة، يمكنك حذف ملف .bak.

س: ما الفرق بين diff وvimdiff؟ ج: diff أداة سطر أوامر تُخرج نتائج مقارنة نصية. vimdiff هو وضع المقارنة المرئية لـvim بشاشة مقسومة جنبًا إلى جنب وتحرير تفاعلي. استخدم diff للمقارنات السريعة، وvimdiff للمعقدة.

س: هل يمكن لـtr التعامل مع المحارف الصينية؟ ج: يمكن، بحذر. المحارف الصينية مرمّزة بـUTF-8 متعددة البايت، وtr يعالج بالبايت، مما قد يقسم المحارف الصينية. للنصوص الصينية، استخدم sed أو Python بدلًا من ذلك.

س: كيف أدمج أوامر معالجة نصوص متعددة بأكثر كفاءة؟ ج: المبدأ هو "تمريرة واحدة، عمليات متعددة." ضع التصفية البسيطة (grep) أولًا لتقليل حجم البيانات، ثم المعالجة الأثقل لاحقًا. تجنب إنشاء أنابيب وسيطة كثيرة في cat file | grep | awk | sed | ....


📖 ملخص


📝 تمارين

  1. أساسي (⭐): استخدم cut لاستخراج أسماء المستخدمين وUIDs (العمود 3) وصدفات الولوج من /etc/passwd، ثم استخدم tr لتحويل محتوى /etc/hostname لأحرف كبيرة
  2. متوسط (⭐⭐): استخدم awk لتصفية ملفات أكبر من 1MB من مخرجات ls -l، ثم استخدم sed لاستبدال رقم منفذ (8080 → 9090) مجمّعًا في ملف إعدادات، مع إنشاء نسخة احتياطية من الأصل
  3. متقدم (⭐⭐⭐): أنشئ ملفي إعدادات مختلفين قليلًا، استخدم diff -u لعرض الاختلافات، ثم اكتب سلسلة أنابيب لاستخراج كل أسطر الأخطاء من ملف سجل، وعدّ الأخطاء حسب الساعة، وأخرج أعلى 5 ساعات ذروة
Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%