ما الفروق بين الأوامر grep وegrep fgrep


محمد أحمد العيل

تشتهر أداة grep بكونها إحدى أدوات البحث الأكثر شهرة في الأنظمة الشبيهة بيونكس Unix-like، سواء تعلّق الأمر بالبحث عن ملفات، سطر أو أسطر عدّة ضمن ملفّ، فهي سريعة وتدعم الكثير من الخيارات مثل: البحث حسب نمط Pattern مكوَّن من سلسلة محارف String والبحث اعتمادًا على تعابير نمطية Regular expressions، بما في ذلك تعابير Perl النمطية Perl reg-ex.

main.png

تتوفّر grep، نظرا لتعدّد وظائفها، على عدّة تنويعات تشمل rgrep، pgrep،fgrep، egrep وغيرها. توجد اختلافات يسيرة بين هذه التنويعات تجعل المبرمجين يستخدمون كلّ تنويعة لمهامّ محدّدة حسب رغبتهم وتفضيلهم.

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

سنستخدم ملفا بالمحتوى التالي ونسمّيه check_file لتطبيق الأوامر في هذا الدرس عليه.

grep is a command that can be used on unix-like systems.
it searches for any string in list of strings or file.
It is very fast.
(f|g)ile 

ملحوظة: لتوافق نتائج تنفيذ الأوامر لديك النتائج المعروضة في هذا الدرس، يجب أن يكون محتوى الملف مطابقا للمحتوى أعلاه: حالة الأحرف +(كبيرة أو صغيرة) وبداية الأسطر. تأكّد كذلك من تنفيذ الأوامر من المجلّد الذي يوجد به الملف، أو اكتب مسار الملف كاملا.

الأمر grep

يعدّ أمر grep الأمر الأساسي في الأنظمة الشبيهة بيونكس للبحث عن مجموعة محارف مهما كان نوعها ضمن سلسلة محارف، ملف، مجموعة ملفات أو ربما نتيجة تنفيذ أمر آخر.

يستخدم الأمر grep التعابير النمطية القاعدية Basic Regular Expressions, BRE في البحث؛ علاوة على سلاسل المحارف الاعتيادية. تفقد المحارف الوصفية Meta characters عند استخدام التعابير النمطية القاعدية قدرتها التعبيرية، ويُتَعامل معها كأي محرف عادي؛ إلا إذا سُبِقت بمحرف تخليص Escape (وهو المحرف \).

نرصُد في ما يلي أهم المحارف الوصفية بالنسبة للأمر grep.

  • +: يعني عند تخليصه أننا نبحث عن السلاسل التي يتكرّر فيها المحرف قبله (على يساره) لمرة واحدة على الأقل. يمكن أن توافق العبارةُ a+b سلاسل المحارف ab، aabcd،aaab وaaaab، إلا أنها لا توافق العبارة bcd.
  • ?: يشير إلى تكرار المحرف الذي قبله لمرة واحدة على الأكثر، حسب طريقة الاستخدام.
  • (: يشير إلى بدء عبارة تناوب Alternation؛ أي موافقة أحد خيارات يفصل بينها الخط العمودي |.
  • ): يشير إلى نهاية عبارة تناوب Alternation.
  • |: يفصل بين الخيارات ضمن عبارة تناوب. يعني التعبير النمطي التالي (a|b)cde “الحرف a أو الحرف b تتبعه الأحرف cde بهذا الترتيب”؛ أي أن العبارتيْن acde وbcde توافقان التعبير النمطي المذكور.
  • {: يشير هذا المحرف إلى بداية محدّدِ مجال.
  • }: يشير هذا المحرف إلى نهاية محدّد مجال. مثلا؛ تعني العبارة التالية a{2} أننا نبحث عن الحرف a مكررا مرتيْن.

راجع مقال مقدّمة في التعابير النمطية للمزيد عن هذه الدلالات واستخداماتها.

ننفّذ الأمر grep بالطريقتيْن التاليتيْن:

grep '(f|g)ile' check_file
grep '\(f|g\)ile' check_file

نلاحظ الفرق في النتيجة:

01_grep.png

يبحث الأمر الأول في الملف check_file عن سلسلة المحارف “(f|g)ile” كما كُتِبت دون أن يُفسّر المحارف (، ) و| تفسيرا خاصًّا. ينتُج عن تنفيذ الأمر إظهار الأسطُر التي تحوي سلسلة المحارف المرغوبة، مع عرض السلسلة بلون مغاير؛ حسب الإعدادات (أحمر في حالتي).
تبدو النتيجة مغايرة بالنسبة للأمر الثاني الذي وضعنا فيه محرف التخليص \ أمام كل محرف نريد أن يُفسَّر بدلالته الخاصّة (محرف وصفي)، وليس كمحرف متضمَّن في الجملة التي نبحث عنها. تُصبح دلالة التعبير النمطي المُمرَّر إلى grep: “الكلمات التي يوجد بها أحد الحرفيْن f أو g متبوعا بالأحرف ile“.
ملحوظة: استخدم الخيار o- إن أردتَ إظهار الكلمة التي تطابق التعبير النمطي لوحدها، دون السطر الذي توجد فيه:

grep -o '(f|g)ile' check_file
grep -o '\(f|g\)ile' check_file

الأمر egrep

يشبه اﻷمر egrep الأمرَ grep مع فرق أنه يتعامل مع المحارف الوصفية مباشرةً دون الحاجة لمحرف تخليص؛ بمعنى أنه يأخذها بدلالتها الخاصة مباشرةً.

نعيد، لفهم الفكرة جيّدًا، تنفيذَ الأمريْن السابقيْن مع إحلال egrep مكان grep:

egrep '(f|g)ile' check_file
egrep '\(f|g\)ile' check_file

02_egrep.png

يبدو الأمر هنا معكوسا: بدون تخليص المحارف الوصفية فإن الأمر egrep يحتفظ بدلالتها الخاصّة، فيبحث في الحالة الأولى عن جميع سلاسل المحارف التي تبدأ بحرف f أو g؛ أما في الحالة الثانية فيعدّ المحارف (، ) و| جزءًا من السلسلة ويبحث بالتالي عن العبارة (f|g)ile كما هي.

ملحوظة: يشبه تنفيذ الأمر egrep تنفيذَ الأمر grep مع الخيار E-:

grep -E '(f|g)ile' check_file
grep -E '\(f|g\)ile' check_file

يُفضّل كثيرون استخدام egrep بدلا من grep للبحث اعتمادًا على تعابير نمطيّة إذ أنها تزيح عن كاهلهم ضرورة تخليص المحارف الوصفية؛ خصوصا في العبارات النمطية المعقدة.

الأمر fgrep

لا يتعامل الأمر fgrep مع التعابير النمطية ولا المحارف الخاصّة؛ فالمعطى المُمرَّر له أولا هو سلسلة محارف ينبغي البحث عنها كما هي. يشبه استخدام fgrep استخدام الأمر grep مع فرق أن الأخير سيفسّر المحرف \ على أنه محرف تخليص، بينما لا يتعرف egrep عليه نهائيا؛ فهو بالنسبة له مجرد محرف كالبقية.

fgrep '(f|g)ile' check_file
fgrep '\(f|g\)ile' check_file

03_fgrep.png

تمكن ملاحظة أن fgrep بحث في كلتا الحالتيْن عن سلسلة المحارف كما مُرِّرت إليه. في الحالة الأولى كانت النتيجة مشابهة لتنفيذ الأمر grep بدون تخليص المحارف، وفي الثانية أضفنا محرف التخليص \؛ إلا أن fgrep لا يعدّه محرفا ذا دلالة خاصّة فيبحث عن السلسلة كما كُتبت ولا يجدها في الملف.

ملحوظة: يشبه تنفيذ الأمر fgrep تنفيذَ الأمر grep مع الخيار F-:

grep -F '(f|g)ile' check_file
grep -F '\(f|g\)ile' check_file

تعرّفنا في هذا الدرس على الفروق الأساسيّة بين ثلاث تنويعات من الأمر grep شائع الاستخدام في البحث عن سلاسل المحارف. يمكنك اختيار التنويعة التي تناسبك حسب الحاجة.

ترجمة بتصرف لمقال What’s Difference Between Grep, Egrep and Fgrep in Linux? لصاحبه Gunjit Khera. 





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن