الفرق بين المراجعتين لصفحة: «Bash/examples using grep»

من موسوعة حسوب
إدخال 2.2 إضافة باقي محتوى فصل أمثلة على grep
إدخال 2.3 إضافة باقي محتوى فصل أمثلة على grep
سطر 1: سطر 1:
== التعابير النمطية Regular Expressions==
==التعابير النمطية Regular Expressions==
التعبير النمطي (Regular Expression) هو أسلوب يصف مجموعة من النصوص (strings)، وتُبنى التعابير النمطية بشكل تناظري للتعابير الحسابية (arithmetic expressions) عبر استخدام عدة معامِلات لدمج التعابير الأصغر. وأصغر وحدة بنائية للتعابير النمطية هي تلك التي تطابق محرفًا واحدًا، فأغلب المحارف -بما في ذلك كل الحروف والأرقام- ما هي إلا تعابير نمطية تطابق أنفسها، ويمكن اقتباس أي محرف خاص (metacharacter) له معنىً خاص بسبقه بشرطة مائلة خلفية <code>\</code>.
التعبير النمطي (Regular Expression) هو أسلوب يصف مجموعة من النصوص (strings)، وتُبنى تلك التعابير النمطية بشكل تناظري للتعابير الحسابية (arithmetic expressions) باستخدام عدة معامِلات لدمج التعابير الأصغر. وأصغر وحدة بنائية للتعابير النمطية هي تلك التي تطابق محرفًا واحدًا، ذلك أن أغلب المحارف -بما في ذلك كل الحروف والأرقام- ما هي إلا تعابير نمطية تطابق أنفسها، ويمكن اقتباس أي محرف خاص (metacharacter) له معنىً خاص بسبْقِه بشرطة مائلة خلفية <code>\</code>.
==المحارف الخاصة للتعابير النمطية==
==المحارف الخاصة للتعابير النمطية==
يمكن إتباع التعبير النمطي بواحد من عدة معامِلات تكرار (محارف خاصة):
يمكن إتْباع التعبير النمطي بواحد من عدة معامِلات تكرار (محارف خاصة):


'''جدول 4.1 معامِلات التعابير الخاصة'''
'''جدول 4.1 معامِلات التعابير النمطية'''
{| class="wikitable"
{| class="wikitable"
!المعامل
!المعامل
سطر 10: سطر 10:
|-
|-
|<code>.</code>
|<code>.</code>
|يطابق أي محرف وحيد.
|يطابق هذا المعامِل أي محرف وحيد.
|-
|-
|<code>?</code>
|<code>?</code>
سطر 34: سطر 34:
|-
|-
|<code>^</code>
|<code>^</code>
|يطابق هذا المحرفُ النص الفارغ في بداية سطر ما، كما يمثل المحارف التي ليست في مدى قائمة ما.
|يطابِق هذا المحرفُ النصَّ الفارغ في بداية سطر ما، كما يمثِّل المحارفَ التي ليست في مدى قائمة ما.
|-
|-
|<code>$</code>
|<code>$</code>
|يطابق هذا المحرف النص الفارغ في نهاية سطر ما.
|يطابِق هذا المحرف النص الفارغ في نهاية سطر ما.
|-
|-
|<code>\b</code>
|<code>\b</code>
|يطابق هذا المحرفُ النصَّ الفارغ (empty string) في نهاية كلمة.
|يطابِق هذا المحرفُ النصَّ الفارغ (empty string) في نهاية كلمة.
|-
|-
|<code>\B</code>
|<code>\B</code>
|يطابق النص الفارغ إن لم يكن في نهاية كلمة.
|يطابِق النص الفارغ إن لم يكن في نهاية كلمة.
|-
|-
|<code>\<</code>
|<code>\<</code>
|يطابق النص الفارغ في بداية كلمة.
|يطابِق النص الفارغ في بداية كلمة.
|-
|-
|<code>\></code>
|<code>\></code>
|يطابق النص الفارغ في نهاية كلمة.
|يطابِق النص الفارغ في نهاية كلمة.
|}يمكن وضع تعبيرين نمطيين في تسلسل (concatenation)، ويكون التعبير الناتج مطابِقًا لأي نص (string) تكوَّن بتسلسل نصيْن فرعيين مطابقيْن -بالترتيب- لتعبيريْن فرعيين متسلسليْن. كذلك يمكن ربط تعبيريْن نمطيين بمعامل الحرف المَزيد <code>|</code>، ويطابق التعبير النمطي الناتج أي نص مطابق لأي من التعبيريْن.
|}يمكن وضع تعبيرين نمطيين في تسلسل (concatenation)، ويكون التعبير الناتج مطابِقًا لأي نص (string) تكوَّن بتسلسل نصيْن فرعيين مطابقيْن -بالترتيب- لتعبيريْن فرعيين متسلسليْن. كذلك يمكن ربط تعبيريْن نمطيين بمعامل الحرف المَزيد <code>|</code>، ويطابق التعبير النمطي الناتج أي نص مطابق لأي من التعبيريْن. ولِلتكرار (Repitition) أولوية أعلى من التسلسل (Concatenation)، والتسلسل بدوره له أولوية أعلى من التناوب (Alternation). ولإلغاء قاعدة الأولوية تلك يمكن وضع تعبير فرعي بالكامل بين قوسين <code>()</code>.
 
للتكرار (Repitition) أولوية أعلى من التسلسل (Concatenation)، والتسلسل بدوره له أولوية أعلى من التناوب (Alternation). ولإلغاء قاعدة الأولوية تلك يمكن وضع تعبير فرعي بالكامل بين قوسين <code>()</code>.
==الفرق بين التعبير النمطي الأساسي والممتد==
==الفرق بين التعبير النمطي الأساسي والممتد==
تفقد المحارف الخاصة التالية معناها في التعابير النمطية الأساسية (Basic Regular Expression): <code>?</code> ، <code>+</code> ، <code>{</code> ، <code>|</code> ، <code>(</code> ، <code>)</code>، وتُستخدم نفس المحارف مسبوقة بشرطة مائلة خلفية بدلًا من ذلك <code>?\</code> , <code>+\</code> , <code>{\</code> , <code>|\</code> , <code>(\</code> , <code>)\</code>. انظر توثيق النظام لديك لترى أي الأوامر التي تستخدم التعابير النمطية تدعم التعابير الممتدة.
تفقد المحارف الخاصة التالية معناها في التعابير النمطية الأساسية (Basic Regular Expression): <code>?</code> ، <code>+</code> ، <code>{</code> ، <code>|</code> ، <code>(</code> ، <code>)</code>، وتُستخدم نفس المحارف مسبوقة بشرطة مائلة خلفية بدلًا من ذلك <code>?\</code> , <code>+\</code> , <code>{\</code> , <code>|\</code> , <code>(\</code> , <code>)\</code>. انظر توثيق النظام لديك لترى أي الأوامر التي تستخدم التعابير النمطية تدعم التعابير الممتدة.
==أمر grep==
==أمر grep==
يبحث أمر <code>grep</code> في ملفات المدخلات عن الأسطر التي تحتوي على تطابقات لقائمة أنماط (patterns) بعينها، وحين يجد تطابقًا في أحد الأسطر فإنه ينسخ السطر إلى مخرج قياسي (standard output) افتراضيًا أو إلى أي مخرج آخر تطلبه باستخدام الخيارات التي قد تضيفها إلى الأمر.
يبحث أمر <code>grep</code> في ملفات المدخلات عن الأسطر التي تحتوي على تطابقات لقائمة أنماط (patterns) بعينها، وحين يجد تطابقًا في أحد الأسطر فإنه ينسخ السطر إلى مخرج قياسي (standard output) افتراضيًا أو إلى أي مخرج آخر تطلُبه باستخدام الخيارات التي قد تضيفَها إلى الأمر.


ورغم أن أمر <code>grep</code> يتوقع أن يجري التطابقات على النصوص إلا أنه ليس له قيود على طول سطر المدخلات باستثناء الذاكرة المتاحة، ويمكنه مطابقة المحارف العشوائية (arbitrary characters) داخل السطر، وإن كان آخر بايت من ملف مدخلات ليس سطرًا جديدًا (newline) فإن <code>grep</code> يضيف واحدًا تلقائيًا. كذلك لا يمكن مطابقة محارف السطر الجديد في نص بما أن السطر الجديد يُعد فاصلًا لقائمة الأنماط. إليك بعض الأمثلة:<syntaxhighlight lang="bash">
ورغم أن أمر <code>grep</code> يتوقع أن يُجري التطابقات على النصوص إلا أنه ليس له قيود على طول سطر المدخلات باستثناء الذاكرة المتاحة، ويمكنه مطابقة المحارف العشوائية (arbitrary characters) داخل السطر، وإن كان آخر بايت من ملف مدخلات ليس سطرًا جديدًا (newline) فإن <code>grep</code> يضيف واحدًا تلقائيًا. كذلك لا يمكن مطابقة محارف السطر الجديد داخل نص (text) بما أن السطر الجديد يُعد فاصلًا لقائمة الأنماط. إليك بعض الأمثلة:<syntaxhighlight lang="bash">
hsoub ~> grep root /etc/passwd
hsoub ~> grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
سطر 87: سطر 85:
/home/hsoub/.bashrc:PS1="\[\033[1;44m\]$USER is in \w\[\033[0m\] "
/home/hsoub/.bashrc:PS1="\[\033[1;44m\]$USER is in \w\[\033[0m\] "
</syntaxhighlight>
</syntaxhighlight>
*يعرض المستخدم <code>hsoub</code> الأسطر التي تحتوي نص <code>root</code> من <code>etc/passwd/</code>.
* يعرض المستخدم <code>hsoub</code> الأسطر التي تحتوي نص <code>root</code> من <code>etc/passwd/</code>.
 
*ثم يعرض أرقام الأسطر التي تحتوي على ذلك النص.
*ثم يعرض أرقام الأسطر التي تحتوي على ذلك النص.
*ثم ينظر في الأمر الثالث أي المستخدمين لا يستخدمون bash، لكن لا يتم عرض الحسابات التي تستخدم صدفة <code>nologin</code>.
*ثم ينظر في الأمر الثالث أي المستخدمين لا يستخدمون bash، لكن لا يتم عرض الحسابات التي تستخدم صدفة <code>nologin</code>.
*ثم يحسب عدد الحسابات التي صدفاتها <code>bin/false/</code>.
*ثم يحسب عدد الحسابات التي صدفاتها <code>bin/false/</code>.
*أما سطر الأوامر الأخير فيعرض الأسطر التي تبدأ بـ <code>bash./~</code> من كل الملفات الموجودة في مجلد المنزل للمستخدم <code>hsoub</code>، باستثناء التطابقات التي تحتوي على نص <code>history</code>، بما في ذلك استبعاد التطابقات التي من ملف <code>bash_history./~</code> بما أنه قد يحتوي على نفس المقطع النصي سواء في حالتيه الصغرى (lowercase) والكبرى (uppercase). لاحظ أيضًا أن البحث عن نص <code>ps</code> وليس عن أمر <code>ps</code>.
*أما سطر الأوامر الأخير فيعرض الأسطر التي تبدأ بـ <code>bash./~</code> من كل الملفات الموجودة في مجلد المنزل للمستخدم <code>hsoub</code>، باستثناء التطابقات التي تحتوي على نص <code>history</code>، بما في ذلك استبعاد التطابقات التي من ملف <code>bash_history./~</code> بما أنه قد يحتوي على نفس المقطع النصي سواء في حالتيه الصغرى (lowercase) والكبرى (uppercase). لاحظ أيضًا أن البحث عن نص <code>ps</code> وليس عن أمر <code>ps</code>.
==أمر grep والتعبيرات النمطية==
==أمر grep والتعابير النمطية==
<blockquote>'''إن كنت على نظام تشغيل خلاف لينكس'''</blockquote><blockquote>نحن نستخدم أمر <code>grep</code> الخاص بنظام جنو في هذه الأمثلة، والذي يدعم التعبيرات النمطية الممتدة، وأمر <code>grep</code> من نظام جنو هو الافتراضي على أنظمة لينكس، فانظر -إن كنت تعمل على أنظمة غير لينكس- أي إصدار لديك باستخدام خيار <code>V-</code>. يمكن تحميل <code>grep</code> الخاص بنظام جنو من https://gnu.org/directory.</blockquote>
<blockquote>'''إن كنت على نظام تشغيل خلاف لينكس'''</blockquote><blockquote>نحن نستخدم أمر <code>grep</code> الخاص بنظام جنو في هذه الأمثلة، والذي يدعم التعبيرات النمطية الممتدة، ذلك أن أمر <code>grep</code> من نظام جنو هو الافتراضي على أنظمة لينكس، فانظر -إن كنت تعمل على أنظمة غير لينكس- أي إصدار لديك باستخدام خيار <code>V-</code>. كما تستطيع تحميل <code>grep</code> الخاص بنظام جنو من https://gnu.org/directory.</blockquote>
 
===محاور الأسطر والكلمات===
=== محاور الأسطر والكلمات ===
سنعرض الآن من المثال السابق الأسطر التي تبدأ بنص <code>root</code>:<syntaxhighlight lang="bash">
سنعرض الآن من المثال السابق الأسطر التي تبدأ بنص root:<syntaxhighlight lang="bash">
hsoub ~> grep ^root /etc/passwd
hsoub ~> grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
</syntaxhighlight>وإن كنا نريد أي الحسابات التي ليس لديها صدفات تم تعيينها لها فإننا نبحث عن الأسطر التي تنتهي بمحرف <code>:</code>، كما يلي:<syntaxhighlight lang="bash">
</syntaxhighlight>وإن كنا نريد رؤية أيّ الحسابات التي لم تعيَّن لها صدفات فسنبحث عن الأسطر التي تنتهي بمحرف <code>:</code>، كما يلي:<syntaxhighlight lang="bash">
hsoub ~> grep :$ /etc/passwd
hsoub ~> grep :$ /etc/passwd
news:x:9:13:news:/var/spool/news:
news:x:9:13:news:/var/spool/news:
سطر 105: سطر 103:
hsoub ~> grep export ~/.bashrc | grep '\<PATH'
hsoub ~> grep export ~/.bashrc | grep '\<PATH'
   export PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"
   export PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"
</syntaxhighlight>بالمثل فإن <code><\</code> تطابق نهاية كلمة ما. وإن كنت تريد نصًا يقع بين مسافتين "كلمة منفصلة" فمن الأفضل أن نستخدم <code>w-</code> كما في المثال التالي حيث نعرض معلومات عن قسم الجذر -root- في القرص الصلب:<syntaxhighlight lang="bash">
</syntaxhighlight>بالمثل فإن <code><\</code> تطابق نهاية كلمة ما، وإن كنت تريد كلمة منفصلة"أي نص (string) يقع بين مسافتين" فمن الأفضل أن تستخدم <code>w-</code> كما في المثال التالي حيث تعرض معلومات عن قسم الجذر -root- في القرص الصلب:<syntaxhighlight lang="bash">
hsoub ~> grep -w / /etc/fstab
hsoub ~> grep -w / /etc/fstab
LABEL=/                /                      ext3    defaults        1 1
LABEL=/                /                      ext3    defaults        1 1
</syntaxhighlight>وإن لم يُستخدم ذلك الخيار فستُعرض جميع الأسطر من جدول نظام الملفات (file system table).
</syntaxhighlight>وإن لم يُستخدم ذلك الخيار فستُعرض جميع الأسطر من جدول نظام الملفات (file system table).
 
===فئات المحارف===
=== فئات المحارف ===
تعبير القوس المربع (bracket expression) هو قائمة من المحارف تقع بين القوسيْن المربعيْن <code>[]</code> ، ويطابِق ذلك التعبيرُ أي محرف وحيد في تلك القائمة، فإن كان أول محرف في القائمة هو رمز الإقحام <code>^</code> فإنه يطابق أي محرف ليس في القائمة، فمثلًا يطابق التعبير النمطي <code>[0123456789]</code> أي محرف وحيد. ويتكون '''مدى التعبير''' (expression range) داخل تعبير القوس المربع <code>[]</code> من محرفيْن يفصل بينهما شرطة <code>-</code>، ويطابِق أي محرف وحيد يصنِّف بين محرفين بما في ذلك استخدام تسلسل الفرز المَحلي (locale's collating sequence) ومجموعة المحارف. فمثلًا في الإعدادات المحلية الافتراضية للغة <code>C</code> فإن <code>[a-d]</code> تساوي <code>[abcd]</code>.
تعبير القوس المربع (bracket expression) هو قائمة من المحارف تقع بين القوسيْن المربعيْن <code>[]</code> ، ويطابِق أي محرف وحيد في تلك القائمة، فإن كان أول محرف في القائمة هي علامة الإقحام <code>^</code> فإنها تطابق أي محرف ليس في القائمة، فمثلًا يطابق التعبير النمطي "[0123456789]" أي محرف وحيد.
 
ويتكون '''مدى التعبير''' داخل تعبير القوس المربع <code>[]</code> من محرفيْن يفصل بينهما شرطة <code>-</code>، ويطابِق أي محرف وحيد يصنِّف بين محرفين بما في ذلك استخدام تسلسل الفرز المَحلي (locale's collating sequence) ومجموعة المحارف. فمثلًا في الإعدادات المحلية الافتراضية للغة <code>C</code> فإن <code>[a-d]</code> تساوي <code>[abcd]</code>.


تصنِّف العديد من الإعدادات المَحلية (locales) المحارفَ وفقًا لترتيب القاموس، وفي تلك المحليِّات فإن <code>[a-d]</code> لا تساوي <code>[abcd]</code>، بل قد تساوي <code>[aBbCcDd]</code> مثلًا. وللحصول على التفسير التقليدي لتعابير القوس المربع يمكنك استخدام الإعدادات المحلية للغة <code>C</code> بضبط متغير البيئة <code>LC_ALL</code> على القيمة <code>C</code>.
تصنِّف العديد من الإعدادات المَحلية (locales) المحارفَ وفقًا لترتيب القاموس، وفي تلك المحليِّات فإن <code>[a-d]</code> لا تساوي <code>[abcd]</code>، بل قد تساوي <code>[aBbCcDd]</code> مثلًا. وللحصول على التفسير التقليدي لتعابير القوس المربع يمكنك استخدام الإعدادات المحلية للغة <code>C</code> بضبط متغير البيئة <code>LC_ALL</code> على القيمة <code>C</code>.


أخيرًا، تُعرَّف بعض فئات المحارف المذكورة تُعرَّف مسبقًا داخل تعابير القوس المربع، انظر صفحات دليل info لأمر grep أو صفحات دليل man من أجل المزيد من المعلومات عن تلك التعابير المعرَّفة مسبقًا. أيضًا، انظر في المثال التالي، حيث ستُعرض كل الأسطر التي تحتوي إما y أو f.<syntaxhighlight lang="bash">
أخيرًا، بعض فئات المحارف المذكورة تُعرَّف مسبقًا داخل تعابير القوس المربع، انظر صفحات دليل <code>info</code> لأمر <code>grep</code> أو صفحات دليل <code>man</code> من أجل المزيد من المعلومات عن تلك التعابير المعرَّفة مسبقًا. أيضًا، انظر في المثال التالي حيث ستُعرض كل الأسطر التي تحتوي إما <code>y</code> أو <code>f</code>.<syntaxhighlight lang="bash">
hsoub ~> grep [yf] /etc/group
hsoub ~> grep [yf] /etc/group
sys:x:3:root,bin,adm
sys:x:3:root,bin,adm
سطر 129: سطر 124:
postfix:x:89:
postfix:x:89:


</syntaxhighlight>استخدم . من أجل تطابق محرف وحيد، فإن أردت الحصول على قائمة لكل كلمات قاموس اللغة الإنجليزية التي تتكون من خمس محارف وتبدأ بحرف c وتنتهي بحرف h فإليك مثالًا على ذلك -مفيد في حل الكلمات المتقاطعة!-:<syntaxhighlight lang="bash">
</syntaxhighlight>استخدم <code>.</code> من أجل تطابق محرف وحيد، فإن أردت الحصول على قائمة لكل كلمات قاموس اللغة الإنجليزية التي تتكون من خمس محارف وتبدأ بحرف <code>c</code> وتنتهي بحرف <code>h</code> فإليك مثالًا على ذلك -مفيد في حل الكلمات المتقاطعة!-:<syntaxhighlight lang="bash">
hsoub ~> grep '\<c...h\>' /usr/share/dict/words
hsoub ~> grep '\<c...h\>' /usr/share/dict/words
catch
catch
سطر 139: سطر 134:
crash
crash
crush
crush
</syntaxhighlight>أما إن أردت عرض الأسطر التي تحتوي على محرف . نفسه فاستخدم خيار F- للحصول عليه. واستخدم محرف * من أجل مطابقة عدة محارف، انظر المثال التالي الذي يختار كل الكلمات التي تبدأ بمحرف c وتنتهي بمحرف h من قاموس النظام:<syntaxhighlight lang="bash">
</syntaxhighlight>أما إن أردت عرض الأسطر التي تحتوي على محرف <code>.</code> نفسه فاستخدم خيار <code>F-</code> للحصول عليه، واستخدم محرف <code>*</code> من أجل مطابقة عدة محارف، انظر المثال التالي الذي يختار كل الكلمات التي تبدأ بمحرف <code>c</code> وتنتهي بمحرف <code>h</code> من قاموس النظام:<syntaxhighlight lang="bash">
hsoub ~> grep '\<c.*h\>' /usr/share/dict/words
hsoub ~> grep '\<c.*h\>' /usr/share/dict/words
caliph
caliph
سطر 147: سطر 142:
cheetah
cheetah
--output omitted--
--output omitted--
</syntaxhighlight>أما إن أردت إيجاد محرف * داخل ملف أو مُخرج ما فاستخدم علامات اقتباس مفردة حوله، فحسوب في المثال التالي يحاول إيجاد محرف النجمة في etc/profile/ بدون علامات التنصيص فلا يعيد له أية أسطر، أما حين يستخدمها فإنه يحصل على نتيجة لما يريده في الخرج:<syntaxhighlight lang="bash">
</syntaxhighlight>أما إن أردت إيجاد محرف <code>*</code> داخل ملف أو مُخرج ما فاستخدم علامات اقتباس مفردة حوله، فحسوب في المثال التالي يحاول إيجاد محرف النجمة في <code>etc/profile/</code> بدون علامات التنصيص فلا يعيد له أية أسطر، أما حين يستخدمها فإنه يحصل على نتيجة لما يريده في الخرج:<syntaxhighlight lang="bash">
hsoub ~> grep * /etc/profile
hsoub ~> grep * /etc/profile


سطر 158: سطر 153:
*[[Bash/shell expansion|التوسعات في Bash]].
*[[Bash/shell expansion|التوسعات في Bash]].
==مصادر==
==مصادر==
*[http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_01.html دليل Bash للمبتدئين، باب التعابير النمطية، فصل التعابير النمطية].
* <span> </span>[http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_01.html دليل Bash للمبتدئين، باب التعابير النمطية، فصل التعابير النمطية].
*[http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_02.html دليل Bash للمبتدئين، باب التعابير النمطية، فصل أمثلة على استخدام grep مع التعابير النمطية].<noinclude>{{DISPLAYTITLE:أمثلة عن استخدام grep في Bash}}</noinclude>
 
* <span> </span>[http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_02.html دليل Bash للمبتدئين، باب التعابير النمطية، فصل أمثلة على استخدام grep مع التعابير النمطية].
<noinclude>{{DISPLAYTITLE:أمثلة عن استخدام grep في Bash}}</noinclude>
[[تصنيف:Bash]]
[[تصنيف:Bash Regular Expressions]]
[[تصنيف:Bash Grep]]

مراجعة 11:32، 24 أغسطس 2018

التعابير النمطية Regular Expressions

التعبير النمطي (Regular Expression) هو أسلوب يصف مجموعة من النصوص (strings)، وتُبنى تلك التعابير النمطية بشكل تناظري للتعابير الحسابية (arithmetic expressions) باستخدام عدة معامِلات لدمج التعابير الأصغر. وأصغر وحدة بنائية للتعابير النمطية هي تلك التي تطابق محرفًا واحدًا، ذلك أن أغلب المحارف -بما في ذلك كل الحروف والأرقام- ما هي إلا تعابير نمطية تطابق أنفسها، ويمكن اقتباس أي محرف خاص (metacharacter) له معنىً خاص بسبْقِه بشرطة مائلة خلفية \.

المحارف الخاصة للتعابير النمطية

يمكن إتْباع التعبير النمطي بواحد من عدة معامِلات تكرار (محارف خاصة):

جدول 4.1 معامِلات التعابير النمطية

المعامل التأثير
. يطابق هذا المعامِل أي محرف وحيد.
? العنصر السابق لهذا المحرف يكون اختياريًا، وسيطابَق مرة واحدة على الأقل.
* سيطابَق العنصر السابق صفرًا أو أكثر من المرات.
+ سيطابَق العنصر السابق مرة أو أكثر.
{N} سيطابَق العنصر السابق بعدد من المرات قدره N تحديدًا.
{N,} سيطابَق العنصر السابق N مرة أو أكثر.
{N,M} سيطابَق العنصر السابق N مرة على الأقل، لكن ليس أكثر من M مرة.
- يمثل هذا المعاملُ المدى (range) إن لم يكن أول أو آخر عنصر في قائمة، أو نقطة النهاية لمدىً في قائمة.
^ يطابِق هذا المحرفُ النصَّ الفارغ في بداية سطر ما، كما يمثِّل المحارفَ التي ليست في مدى قائمة ما.
$ يطابِق هذا المحرف النص الفارغ في نهاية سطر ما.
\b يطابِق هذا المحرفُ النصَّ الفارغ (empty string) في نهاية كلمة.
\B يطابِق النص الفارغ إن لم يكن في نهاية كلمة.
\< يطابِق النص الفارغ في بداية كلمة.
\> يطابِق النص الفارغ في نهاية كلمة.

يمكن وضع تعبيرين نمطيين في تسلسل (concatenation)، ويكون التعبير الناتج مطابِقًا لأي نص (string) تكوَّن بتسلسل نصيْن فرعيين مطابقيْن -بالترتيب- لتعبيريْن فرعيين متسلسليْن. كذلك يمكن ربط تعبيريْن نمطيين بمعامل الحرف المَزيد |، ويطابق التعبير النمطي الناتج أي نص مطابق لأي من التعبيريْن. ولِلتكرار (Repitition) أولوية أعلى من التسلسل (Concatenation)، والتسلسل بدوره له أولوية أعلى من التناوب (Alternation). ولإلغاء قاعدة الأولوية تلك يمكن وضع تعبير فرعي بالكامل بين قوسين ().

الفرق بين التعبير النمطي الأساسي والممتد

تفقد المحارف الخاصة التالية معناها في التعابير النمطية الأساسية (Basic Regular Expression): ? ، + ، { ، | ، ( ، )، وتُستخدم نفس المحارف مسبوقة بشرطة مائلة خلفية بدلًا من ذلك ?\ , +\ , {\ , |\ , (\ , )\. انظر توثيق النظام لديك لترى أي الأوامر التي تستخدم التعابير النمطية تدعم التعابير الممتدة.

أمر grep

يبحث أمر grep في ملفات المدخلات عن الأسطر التي تحتوي على تطابقات لقائمة أنماط (patterns) بعينها، وحين يجد تطابقًا في أحد الأسطر فإنه ينسخ السطر إلى مخرج قياسي (standard output) افتراضيًا أو إلى أي مخرج آخر تطلُبه باستخدام الخيارات التي قد تضيفَها إلى الأمر.

ورغم أن أمر grep يتوقع أن يُجري التطابقات على النصوص إلا أنه ليس له قيود على طول سطر المدخلات باستثناء الذاكرة المتاحة، ويمكنه مطابقة المحارف العشوائية (arbitrary characters) داخل السطر، وإن كان آخر بايت من ملف مدخلات ليس سطرًا جديدًا (newline) فإن grep يضيف واحدًا تلقائيًا. كذلك لا يمكن مطابقة محارف السطر الجديد داخل نص (text) بما أن السطر الجديد يُعد فاصلًا لقائمة الأنماط. إليك بعض الأمثلة:

hsoub ~> grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

hsoub ~> grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
12:operator:x:11:0:operator:/root:/sbin/nologin

hsoub ~> grep -v bash /etc/passwd | grep -v nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
news:x:9:13:news:/var/spool/news:
mailnull:x:47:47::/var/spool/mqueue:/dev/null
xfs:x:43:43:X Font Server:/etc/X11/fs:/bin/false
rpc:x:32:32:Portmapper RPC user:/:/bin/false
nscd:x:28:28:NSCD Daemon:/:/bin/false
named:x:25:25:Named:/var/named:/bin/false
squid:x:23:23::/var/spool/squid:/dev/null
ldap:x:55:55:LDAP User:/var/lib/ldap:/bin/false
apache:x:48:48:Apache:/var/www:/bin/false

hsoub ~> grep -c false /etc/passwd
7

hsoub ~> grep -i ps ~/.bash* | grep -v history
/home/hsoub/.bashrc:PS1="\[\033[1;44m\]$USER is in \w\[\033[0m\] "
  • يعرض المستخدم hsoub الأسطر التي تحتوي نص root من etc/passwd/.
  • ثم يعرض أرقام الأسطر التي تحتوي على ذلك النص.
  • ثم ينظر في الأمر الثالث أي المستخدمين لا يستخدمون bash، لكن لا يتم عرض الحسابات التي تستخدم صدفة nologin.
  • ثم يحسب عدد الحسابات التي صدفاتها bin/false/.
  • أما سطر الأوامر الأخير فيعرض الأسطر التي تبدأ بـ bash./~ من كل الملفات الموجودة في مجلد المنزل للمستخدم hsoub، باستثناء التطابقات التي تحتوي على نص history، بما في ذلك استبعاد التطابقات التي من ملف bash_history./~ بما أنه قد يحتوي على نفس المقطع النصي سواء في حالتيه الصغرى (lowercase) والكبرى (uppercase). لاحظ أيضًا أن البحث عن نص ps وليس عن أمر ps.

أمر grep والتعابير النمطية

إن كنت على نظام تشغيل خلاف لينكس

نحن نستخدم أمر grep الخاص بنظام جنو في هذه الأمثلة، والذي يدعم التعبيرات النمطية الممتدة، ذلك أن أمر grep من نظام جنو هو الافتراضي على أنظمة لينكس، فانظر -إن كنت تعمل على أنظمة غير لينكس- أي إصدار لديك باستخدام خيار V-. كما تستطيع تحميل grep الخاص بنظام جنو من https://gnu.org/directory.

محاور الأسطر والكلمات

سنعرض الآن من المثال السابق الأسطر التي تبدأ بنص root:

hsoub ~> grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash

وإن كنا نريد رؤية أيّ الحسابات التي لم تعيَّن لها صدفات فسنبحث عن الأسطر التي تنتهي بمحرف :، كما يلي:

hsoub ~> grep :$ /etc/passwd
news:x:9:13:news:/var/spool/news:

ولكي تعرف ما إن تم تصدير متغير PATH في ملف bashrc./~، فاختر أولًا أسطر export ثم ابحث عن الأسطر التي تبدأ بنص PATH كي لا تعرض MANPATH والمسارات الأخرى المحتملة:

hsoub ~> grep export ~/.bashrc | grep '\<PATH'
  export PATH="/bin:/usr/lib/mh:/lib:/usr/bin:/usr/local/bin:/usr/ucb:/usr/dbin:$PATH"

بالمثل فإن <\ تطابق نهاية كلمة ما، وإن كنت تريد كلمة منفصلة"أي نص (string) يقع بين مسافتين" فمن الأفضل أن تستخدم w- كما في المثال التالي حيث تعرض معلومات عن قسم الجذر -root- في القرص الصلب:

hsoub ~> grep -w / /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1

وإن لم يُستخدم ذلك الخيار فستُعرض جميع الأسطر من جدول نظام الملفات (file system table).

فئات المحارف

تعبير القوس المربع (bracket expression) هو قائمة من المحارف تقع بين القوسيْن المربعيْن [] ، ويطابِق ذلك التعبيرُ أي محرف وحيد في تلك القائمة، فإن كان أول محرف في القائمة هو رمز الإقحام ^ فإنه يطابق أي محرف ليس في القائمة، فمثلًا يطابق التعبير النمطي [0123456789] أي محرف وحيد. ويتكون مدى التعبير (expression range) داخل تعبير القوس المربع [] من محرفيْن يفصل بينهما شرطة -، ويطابِق أي محرف وحيد يصنِّف بين محرفين بما في ذلك استخدام تسلسل الفرز المَحلي (locale's collating sequence) ومجموعة المحارف. فمثلًا في الإعدادات المحلية الافتراضية للغة C فإن [a-d] تساوي [abcd].

تصنِّف العديد من الإعدادات المَحلية (locales) المحارفَ وفقًا لترتيب القاموس، وفي تلك المحليِّات فإن [a-d] لا تساوي [abcd]، بل قد تساوي [aBbCcDd] مثلًا. وللحصول على التفسير التقليدي لتعابير القوس المربع يمكنك استخدام الإعدادات المحلية للغة C بضبط متغير البيئة LC_ALL على القيمة C.

أخيرًا، بعض فئات المحارف المذكورة تُعرَّف مسبقًا داخل تعابير القوس المربع، انظر صفحات دليل info لأمر grep أو صفحات دليل man من أجل المزيد من المعلومات عن تلك التعابير المعرَّفة مسبقًا. أيضًا، انظر في المثال التالي حيث ستُعرض كل الأسطر التي تحتوي إما y أو f.

hsoub ~> grep [yf] /etc/group
sys:x:3:root,bin,adm
tty:x:5:
mail:x:12:mail,postfix
ftp:x:50:
nobody:x:99:
floppy:x:19:
xfs:x:43:
nfsnobody:x:65534:
postfix:x:89:

استخدم . من أجل تطابق محرف وحيد، فإن أردت الحصول على قائمة لكل كلمات قاموس اللغة الإنجليزية التي تتكون من خمس محارف وتبدأ بحرف c وتنتهي بحرف h فإليك مثالًا على ذلك -مفيد في حل الكلمات المتقاطعة!-:

hsoub ~> grep '\<c...h\>' /usr/share/dict/words
catch
clash
cloth
coach
couch
cough
crash
crush

أما إن أردت عرض الأسطر التي تحتوي على محرف . نفسه فاستخدم خيار F- للحصول عليه، واستخدم محرف * من أجل مطابقة عدة محارف، انظر المثال التالي الذي يختار كل الكلمات التي تبدأ بمحرف c وتنتهي بمحرف h من قاموس النظام:

hsoub ~> grep '\<c.*h\>' /usr/share/dict/words
caliph
cash
catch
cheesecloth
cheetah
--output omitted--

أما إن أردت إيجاد محرف * داخل ملف أو مُخرج ما فاستخدم علامات اقتباس مفردة حوله، فحسوب في المثال التالي يحاول إيجاد محرف النجمة في etc/profile/ بدون علامات التنصيص فلا يعيد له أية أسطر، أما حين يستخدمها فإنه يحصل على نتيجة لما يريده في الخرج:

hsoub ~> grep * /etc/profile

hsoub ~> grep '*' /etc/profile
for i in /etc/profile.d/*.sh ; do

انظر أيضًا

مصادر