تخطَّ إلى المحتوى

البحث في Linux: grep و find بالتفصيل

الدرس 6 من 10 · أساسيات Linux

ملف سجلات فيه مئة ألف سطر، والخطأ الذي تبحث عنه في سطر واحد منها. ومشروع فيه آلاف الملفات، وتريد كل ملف كُتبت فيه كلمة TODO. هذه مواقف يومية لكل من يعمل على Linux، وحلها أمران: grep يبحث داخل الملفات، و find يبحث عن الملفات. رأيتهما سريعاً في درس الملفات، والآن ستتقنهما.

سنعمل في مجلد فيه ملف السجلات logs/app.log (ثمانية أسطر)، ومجلد projects/site فيه ملفات موقع، وبعض الملفات الأخرى.

نافذة طرفيّة
grep ERROR logs/app.log
الناتج
2026-11-10 09:10:03 ERROR Database connection failed
2026-11-10 09:10:09 ERROR Database connection failed

grep نص ملف: يطبع كل سطر يحتوي النص. تخيّله مثل قلم التظليل: يمر على الصفحات كلها ويُخرج لك الأسطر التي فيها كلمتك فقط.

والبحث حساس لحالة الحروف: في الملف سطر ثالث فيه error بحروف صغيرة لم يظهر. لتجاهل الحالة أضف -i:

نافذة طرفيّة
grep -i error logs/app.log
الناتج
2026-11-10 09:10:03 ERROR Database connection failed
2026-11-10 09:10:09 ERROR Database connection failed
2026-11-10 09:15:00 error cache write failed
نافذة طرفيّة
grep -n ERROR logs/app.log
الناتج
4:2026-11-10 09:10:03 ERROR Database connection failed
6:2026-11-10 09:10:09 ERROR Database connection failed

-n تضيف رقم السطر، فتذهب إليه في المحرر مباشرة.

نافذة طرفيّة
grep -c INFO logs/app.log
الناتج
4

-c تعدّ الأسطر المطابقة بدل طباعتها.

نافذة طرفيّة
grep -v INFO logs/app.log
الناتج
2026-11-10 09:07:45 WARNING Disk usage at 85%
2026-11-10 09:10:03 ERROR Database connection failed
2026-11-10 09:10:09 ERROR Database connection failed
2026-11-10 09:15:00 error cache write failed

-v تعكس البحث: الأسطر التي لا تحتوي النص. مفيدة لإخفاء الضجيج ورؤية المهم.

الخيار الوظيفة
-i تجاهل حالة الحروف
-n عرض رقم السطر
-c عدّ الأسطر المطابقة
-v الأسطر غير المطابقة
-w الكلمة كاملة فقط: in لا تطابق INFO
-A 2 اعرض سطرين بعد كل نتيجة، و -B قبلها

-r تبحث في المجلد وكل ما تحته:

نافذة طرفيّة
grep -r TODO .
الناتج
./notes.txt:TODO call Omar
./projects/site/app.js:// TODO: validate form
./projects/site/index.html:<!-- TODO: add footer -->

النقطة . تعني المجلد الحالي، وقبل كل نتيجة اسم ملفها. وإذا أردت أسماء الملفات فقط استخدم -l، ولحصر البحث في نوع معيّن استخدم --include:

نافذة طرفيّة
grep -rn --include="*.js" TODO .
الناتج
./projects/site/app.js:1:// TODO: validate form

grep لا يبحث عن نص حرفي فقط، بل عن أنماط. أهمها:

نافذة طرفيّة
grep -E "ERROR|WARNING" logs/app.log
الناتج
2026-11-10 09:07:45 WARNING Disk usage at 85%
2026-11-10 09:10:03 ERROR Database connection failed
2026-11-10 09:10:09 ERROR Database connection failed

-E تفعّل الأنماط الموسعة، والعلامة | تعني «أو».

نافذة طرفيّة
grep "failed$" logs/app.log
الناتج
2026-11-10 09:10:03 ERROR Database connection failed
2026-11-10 09:10:09 ERROR Database connection failed
2026-11-10 09:15:00 error cache write failed
الرمز المعنى مثال
^ بداية السطر ^2026 أسطر تبدأ بـ 2026
$ نهاية السطر failed$ أسطر تنتهي بـ failed
. أي حرف واحد h.t تطابق hat و hot
a|b مع -E هذا أو ذاك ERROR|WARNING

هذه الأنماط اسمها التعابير النمطية (Regular Expressions)، وهي لغة كاملة ستقابلها في كل لغات البرمجة.

find يبحث عن الملفات نفسها حسب خصائصها: الاسم، والنوع، والحجم، وتاريخ التعديل.

نافذة طرفيّة
find . -name "*.log"
الناتج
./logs/app.log
./logs/old/app-2025.log

find مكان شروط: ابدأ من المجلد الحالي . وانزل في كل المجلدات الفرعية. تخيّله مثل أمين مخزن يمشي في كل الممرات ويفتح كل الصناديق بحثاً عما وصفته له.

-name حساسة لحالة الحروف، و -iname تتجاهلها:

نافذة طرفيّة
find . -name "report.txt"
find . -iname "report.txt"
الناتج
./Documents/Report.txt

الأمر الأول لم يجد شيئاً، لأن اسم الملف يبدأ بحرف كبير.

نافذة طرفيّة
find . -type d
الناتج
.
./Documents
./logs
./logs/old
./projects
./projects/site
الشرط المعنى
-type f و -type d ملفات فقط، أو مجلدات فقط
-size +10M أكبر من 10 ميغابايت، و -size -1k أصغر من كيلوبايت
-mtime -7 عُدّل خلال آخر 7 أيام، و +30 قبل أكثر من 30 يوماً
-empty ملفات ومجلدات فارغة
-maxdepth 1 لا تنزل أعمق من مستوى واحد

والشروط تُجمع، فيجب أن تتحقق كلها: find . -type f -name "*.log" -size +10M تجد ملفات السجلات الضخمة التي تملأ القرص.

نفّذ أمراً على كل نتيجة

Section titled “نفّذ أمراً على كل نتيجة”

قوة find الحقيقية أنه لا يكتفي بعرض النتائج. -exec تنفّذ أمراً على كل ملف يجده:

نافذة طرفيّة
find projects -name "*.js" -exec wc -l {} \;
الناتج
3 projects/site/app.js
  • {}: مكان يوضع فيه اسم كل ملف.
  • \;: علامة نهاية الأمر.

والحذف له خيار خاص:

نافذة طرفيّة
find . -name "*.tmp"
الناتج
./logs/session.tmp
./projects/site/cache.tmp
نافذة طرفيّة
find . -name "*.tmp" -delete

بعدها يُرجع البحث نفسه نتيجة فارغة: حُذف الملفان.

find يختار الملفات، و grep يبحث داخلها:

نافذة طرفيّة
find . -name "*.log" -exec grep -c ERROR {} \;
الناتج
2
1

خطآن في السجل الحالي وخطأ في القديم.

  1. أنشئ ملفاً log.txt فيه عشرة أسطر، بعضها يحتوي ok وبعضها fail وواحد FAIL.
  2. اعرض أسطر الفشل كلها مع أرقامها (تلميح: -i و -n)، ثم عدّها بـ -c.
  3. اعثر على كل الملفات التي تنتهي بـ .txt في مجلدك الشخصي ولا تنزل أعمق من مستويين.
  4. تحدٍّ: اعثر على كل ملفات .txt التي تحتوي الكلمة fail، باستخدام find مع -exec grep -l.
  • نسيان علامات التنصيص مع النجمة: find . -name *.log قد تفسر الطرفية النجمة قبل find فتتغير النتيجة. اكتب "*.log".
  • نسيان -r مع مجلد: grep TODO projects يعطي grep: projects: Is a directory.
  • نسيان \; بعد -exec: يعطي find: missing argument to '-exec'.
  • الخلط بين الأمرين: grep للبحث في المحتوى، و find للبحث عن الملفات بـ خصائصها.

سؤال

أي أمر يعرض الأسطر التي لا تحتوي الكلمة DEBUG في ملف app.log؟

سؤال

ما الذي يبحث عنه الأمر find . -type d -name "test"؟

  • grep نص ملف يطبع الأسطر المطابقة، و -i و -n و -c و -v أهم خياراته.
  • grep -r يبحث في مجلد كامل، و -E مع | و ^ و $ لأنماط أقوى.
  • find مكان شروط يبحث عن الملفات بالاسم والنوع والحجم والتاريخ.
  • -exec أمر {} \; ينفّذ أمراً على كل نتيجة، و -delete يحذف.
  • اعرض النتائج أولاً قبل أي حذف، وضع الأنماط بين علامتي تنصيص.