Linux: البحث في النص — grep والتعبيرات النمطية
إيجاد ذلك السطر بين آلاف الملفات — هذه تخصص grep. ربما هو أكثر أمر استخدامًا على لينكس.
📋 المتطلبات المسبقة: يجب إكمال
- الدرس 13: الأنابيب والمرشحات
1. ما ستتعلمه
- البحث الأساسي بـgrep وخياراته الشائعة
- البحث التكراري في الكود بـgrep -r
- التعبيرات النمطية الأساسية
- التعبيرات النمطية الموسعة
- تحليل السجلات في الممارسة
2. قصة البحث عن كود عبر مئة ملف
(1) نقطة الألم: تغيير اسم واجهة برمجة، لكن لست متأكدًا أي ملفات تستخدمها
احتاج شياو مينغ تغيير كل الاستدعاءات من requests.get إلى httpx.get في ملفات Python. المشروع يضم أكثر من 100 ملف — فتحها واحدًا واحدًا كان مستحيلًا.
(2) البحث التكراري بـgrep
grep -rn "requests\.get" --include="*.py" src/
المخرجات:
src/api/client.py:15: response = requests.get(url, headers=headers)
src/api/users.py:42: data = requests.get(f"{API_URL}/users")
src/api/orders.py:78: result = requests.get(ORDER_URL)
3 ملفات بها استدعاءات — وُجدت في أقل من ثانية.
(3) الفائدة: من إبرة في كومة قش إلى دقة الإصابة
كوّن شياو مينغ عادة: قبل تغيير الكود، استخدم grep -rn لإيجاد كل المواقع ذات الصلة، وأكّد منها، ثم ابدأ التحرير.
3. نقاط المعرفة
(1) الاستخدام الأساسي لـgrep
# بحث أساسي
grep "pattern" filename
# مجموعات خيارات شائعة
grep -rn "TODO" src/ # بحث تكراري، عرض أرقام الأسطر
grep -i "error" log.txt # تجاهل حالة الأحرف
grep -v "debug" log.txt # تطابق عكسي (أسطر لا تحتوي debug)
grep -c "failed" log.txt # عدّ فقط
grep -l "main" *.py # عرض أسماء الملفات المطابقة فقط
grep -A5 -B5 "exception" log.txt # عرض 5 أسطر قبل وبعد التطابق
| الخيار | المعنى |
|---|---|
-i |
تجاهل حالة الأحرف |
-v |
تطابق عكسي (عرض الأسطر غير المطابقة) |
-c |
إخراج عدد الأسطر المطابقة فقط |
-n |
عرض أرقام الأسطر |
-r أو -R |
بحث تكراري عبر الدلائل الفرعية |
-l |
عرض أسماء الملفات المطابقة فقط |
-L |
عرض أسماء الملفات غير المطابقة فقط |
-w |
تطابق كلمات كاملة |
-A NUM |
عرض NUM سطر بعد التطابق |
-B NUM |
عرض NUM سطر قبل التطابق |
-C NUM |
عرض NUM سطر قبل وبعد التطابق |
(2) التعبيرات النمطية الأساسية
| محرف نمطي | المعنى | مثال |
|---|---|---|
. |
مطابقة أي محرف واحد | h.t يطابق hit / hot / hat |
^ |
بداية السطر | ^root يطابق أسطر تبدأ بـroot |
$ |
نهاية السطر | bash$ يطابق أسطر تنتهي بـbash |
* |
المحرف السابق مكرر 0 أو أكثر | ab*c يطابق ac / abc / abbc |
[abc] |
مطابقة أي محرف في المجموعة | [Hh]ello يطابق Hello أو hello |
[^abc] |
مطابقة محارف ليست في المجموعة | [^0-9] يطابق محارف غير أرقام |
\< |
بداية كلمة | \<root يطابق root في بداية كلمة |
\> |
نهاية كلمة | root\> يطابق root في نهاية كلمة |
. يطابق أي محرف واحد — إذا احتجت مطابقة نقطة حرفية (مثل عنوان IP)، يجب تخطيها بشرطة مائلة عكسية: grep "192\.168\." file بدلًا من grep "192.168." file (الأخير سيطابق 192X168Y وغيرها بشكل خاطئ).
(3) التعبيرات النمطية الموسعة (grep -E)
في التعبيرات النمطية الأساسية، + و? و| و{} و() تحتاج تخطيًا. التعبيرات الموسعة تستخدم هذه المحارف النمطية مباشرة (عبر grep -E أو egrep):
ℹ️ ملاحظة: الفرق الرئيسي بين التعبيرات النمطية الأساسية والموسعة هو أن في التعبيرات الموسعة (
grep -E)،+و?و|و{}و()يمكن استخدامها بدون تخطي بشرطة مائلة عكسية. في الأساسية،grep "error\|warning"يتطلب تخطي|، بينماgrep -E "error|warning"لا يحتاج. فضّلgrep -Eلصياغة أوضح.
| محرف نمطي | المعنى | مثال |
|---|---|---|
+ |
المحرف السابق مكرر مرة أو أكثر | ab+c يطابق abc / abbc لكن لا يطابق ac |
? |
المحرف السابق يظهر 0 أو 1 مرة | colou?r يطابق color أو colour |
| ` | ` | أو |
{n,m} |
تكرار من n إلى m مرة | [0-9]{3,5} يطابق أرقامًا من 3-5 خانات |
() |
تجميع | `(error |
(4) ▶ مثال: بحث أساسي
# البحث في ملف
grep "root" /etc/passwd
# root:x:0:0:root:/root:/bin/bash
# تجاهل حالة الأحرف
echo -e "Error\nerror\nERROR" | grep -i "error"
# الأسطر الثلاثة كلها مطابقة
# العدّ
grep -c "nologin" /etc/passwd
# Output: 16
# عرض أرقام الأسطر
grep -n "www-data" /etc/passwd
# 33:www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
الإخراج:
TEXTroot:x:0:0:root:/root:/bin/bash Error error ERROR 16 33:www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
(5) ▶ مثال: التطابق العكسي
# استبعاد أسطر التعليقات
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"
# استبعاد سجلات التصحيح
grep -v "DEBUG" app.log | grep "ERROR"
# استبعاد ملفات بامتدادات معينة
ls -la | grep -v "\.md$"
الإخراج:
TEXTPort 22 PermitRootLogin no PasswordAuthentication no 2026-07-07 10:23:45 ERROR Database connection failed 2026-07-07 10:24:12 ERROR Timeout waiting for response drwxr-xr-x 2 alice alice 4096 Jul 7 10:00 src -rw-r--r-- 1 alice alice 1234 Jul 7 10:00 config.yaml
(6) ▶ مثال: بحث تكراري في الكود
# البحث عن كل تعليقات TODO في المشروع
grep -rn "TODO\|FIXME\|HACK" --include="*.py" src/
# البحث في أنواع ملفات محددة
grep -rn "def " --include="*.py" --include="*.js" .
# البحث مع استبعاد node_modules
grep -rn "api_key" --exclude-dir=node_modules --exclude-dir=.git .
# عرض أسماء الملفات فقط
grep -rl "class User" src/
الإخراج:
TEXTsrc/api/client.py:23:# TODO: Add retry logic src/models/user.py:45:# FIXME: Handle edge case src/utils/helpers.py:12:# HACK: Temporary workaround src/api/client.py:10:def get_user(user_id): src/models/user.py:5:def validate_email(email): config/settings.py:3:api_key = "sk-xxx" src/models/user.py src/auth.py
grep -rn هو المزيج الذهبي للبحث في الكود — -r يبحث تكراريًا في الدلائل، و-n يعرض أرقام الأسطر، و--include يحد أنواع الملفات. في المشاريع الكبيرة، grep -rn "pattern" --include="*.py" src/ يمكنه تحديد موقع الكود المستهدف خلال ثانية.
(7) ▶ مثال: استخدام السياق
# عرض 3 أسطر قبل وبعد التطابق
grep -C 3 "NullPointerException" app.log
# عرض 5 أسطر بعد التطابق
grep -A 5 "Traceback" python_error.log
# عرض 2 سطر قبل التطابق
grep -B 2 "500" access.log
الإخراج:
TEXT10:23:01 INFO Processing request 10:23:02 WARN Memory usage high 10:23:03 ERROR NullPointerException at UserService.java:45 10:23:04 INFO Retrying operation 10:23:05 WARN Connection pool low Traceback (most recent call last): File "app.py", line 42, in handle_request result = process(data) File "processor.py", line 15, in process return transform(input) ValueError: Invalid input data 192.168.1.100 - - [07/Jul/2026:10:23:44] "POST /api/data" 192.168.1.100 - - [07/Jul/2026:10:23:45] "POST /api/data HTTP/1.1" 500 0
(8) ▶ مثال: التعبيرات النمطية في الممارسة
# مطابقة عناوين البريد الإلكتروني
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" contacts.txt
# مطابقة عناوين IP
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" access.log
# مطابقة عناوين URL
grep -E "https?://[^ ]+" index.html
# مطابقة تواريخ (YYYY-MM-DD)
grep -E "[0-9]{4}-[0-9]{2}-[0-9]{2}" logs/*.log
# مطابقة أسطر تبدأ برقم وتنتهي بحرف
grep "^[0-9].*[a-zA-Z]$" file.txt
الإخراج:
TEXTalice@example.com bob.smith@company.org contact@my-site.net 192.168.1.100 - - [07/Jul/2026] ... 10.0.0.45 - - [07/Jul/2026] ... https://example.com/api/users http://internal.server.local/status 2026-07-07 2026-07-08 1abc 23x
(9) ▶ مثال شامل: تحليل أخطاء السجلات
#!/bin/bash
# analyze-errors.sh - Log error analysis
LOG_FILE="${1:-/var/log/syslog}"
echo "=== Error Analysis Report ==="
echo "Source file: $LOG_FILE"
echo ""
echo "1. Error count by type:"
grep -i "error" "$LOG_FILE" | awk '{print $5}' | sort | uniq -c | sort -rn | head -10
echo ""
echo "2. Last 5 errors:"
grep -i "error" "$LOG_FILE" | tail -5
echo ""
echo "3. Critical alerts (OOM / Disk Full / Connection Refused):"
grep -iE "oom|out of memory|disk full|no space left|connection refused" "$LOG_FILE"
echo ""
echo "4. Error trend (by hour):"
grep -i "error" "$LOG_FILE" | grep -oP "\d{2}:\d{2}" | cut -d: -f1 | sort | uniq -c | sort -rn
❓ أسئلة شائعة
س: ما الفرق بين grep والتعبيرات النمطية؟ ج: grep أداة سطر أوامر للبحث عن أسطر تطابق نمطًا في الملفات؛ التعبيرات النمطية (regex) هي صياغة لوصف أنماط النص. grep يدعم التعبيرات النمطية كأنماط بحث، لكن regex في حد ذاتها صياغة فقط يمكن استخدامها أيضًا في sed وawk وPython والعديد من الأدوات واللغات الأخرى.
س: هل
grep -rوgrep -Rنفس الشيء؟ ج: أساسًا نعم.-Rيتبع الروابط الرمزية، بينما-rلا يتبعها افتراضيًا. أي منهما يعمل جيدًا للاستخدام اليومي.
س: كيف أبحث متجاهلًا حالة الأحرف؟ ج: استخدم الخيار
-i:grep -ir "error" /var/log/.
س: لماذا يفشل grep أحيانًا في إيجاد المحارف الصينية؟ ج: قد تكون هذه مشكلة لغة. المحارف الصينية متعددة البايت في ترميز UTF-8، و
grepيطابق بالبايت افتراضيًا. جرّبexport LANG=zh_CN.UTF-8أوgrep -P(وضع regex الخاص بـPerl).
س: ما فائدة
grep -v؟ ج: التطابق العكسي — يُخرج الأسطر التي لا تطابق النمط. مع استدعاءات grep أخرى، يمكنه "استبعاد" أسطر معينة، مثلgrep -v "^#"يستبعد أسطر التعليقات، وgrep -v "^$"يستبعد الأسطر الفارغة.
📖 ملخص
grep "pattern" fileيبحث في الملفات، و-rتكراري في الدلائل، و-nيعرض أرقام الأسطر- التعبيرات النمطية الأساسية:
.أي محرف، و^بداية سطر، و$نهاية سطر، و*تكرار، و[abc]مجموعة محارف - التعبيرات النمطية الموسعة (
grep -E):+مرة أو أكثر، و?صفر أو مرة، و|أو، و()تجميع -vعكسي، و-iتجاهل حالة، و-cعدّ، و-lعرض أسماء الملفات فقط-A/-B/-Cعرض أسطر السياق
📝 تمارين
- أساسي (⭐): ابحث في
/etc/passwdعن المستخدمين الذين يملكون/bin/bashكصدفة ولوج، ثم ابحث في ملف سجل عن الأخطاء واستخدم-cلعدّها - متوسط (⭐⭐): ابحث تكراريًا في دليل مشروع عن كل تعليقات FIXME وTODO، ثم استخدم
grep -vلاستبعاد دليل .git واعدد إجمالي أسطر الكود - متقدم (⭐⭐⭐): استخدم التعبيرات النمطية لمطابقة كل عناوين IP في ملف سجل، ثم ادمج
sortوuniq -cلعدّ التكرارات لكل IP وإيجاد أكثر 10 عناوين IP تكرارًا