في بعض الأحيان، في نصوص Linux، قد ترغب في معرفة ما إذا كان سلسلة نصية تحتوي على سلسلة نصية محددة وأصغر حجمًا. هناك العديد من الطرق للقيام بذلك. سنعرض لك بعض التقنيات البسيطة والموثوقة.
لماذا هذا مفيد؟
يعد البحث عن سلسلة فرعية أصغر في سلسلة شرطًا شائعًا. ومن الأمثلة على ذلك قراءة نص من ملف أو من إدخال بشري والبحث في السلسلة عن سلسلة فرعية محددة حتى يتمكن البرنامج النصي الخاص بك من تحديد ما يجب القيام به بعد ذلك. قد يكون البحث عن تسمية أو اسم جهاز في ملف تكوين أو سلسلة أوامر في سطر إدخال من مستخدم.
يتمتع مستخدمو Linux بعدد كبير من الأدوات المساعدة لمعالجة النصوص. بعضها مدمج في غلاف Bash، والبعض الآخر متوفر كأدوات مساعدة أو تطبيقات مستقلة. هناك سبب وراء تزويد أنظمة التشغيل المشتقة من Unix بقدرات معالجة السلاسل بشكل غني.
بعض الأشياء التي تبدو وكأنها ملفات ليست ملفات بسيطة. إنها ملفات خاصة تمثل أشياء مثل الأجهزة ومصادر معلومات النظام. التجريد الذي يقوم به نظام التشغيل يعطيها مظهر وخصائص الملفات. يمكنك قراءة المعلومات منها – كنص، بطبيعة الحال – وفي بعض الحالات الكتابة عليها، لكنها ليست ملفات عادية.
يُستخدم النص أيضًا كمدخل ومخرج للأوامر في نافذة المحطة الطرفية. وهذا يسمح بإعادة توجيه المدخلات والمخرجات وتوزيعها. وتدعم هذه الوظيفة القدرة على ربط تسلسلات أوامر Linux معًا، وتمرير المخرجات من أمر واحد كمدخل إلى الأمر التالي.
بغض النظر عن أصول النص الذي نتلقاه، فإن البحث عن كلمة مهمة أو أمر أو تسمية أو أي مؤشر آخر يشكل جزءًا أساسيًا من التعامل مع البيانات المستندة إلى النص. فيما يلي مجموعة من التقنيات البسيطة التي يمكنك تضمينها في نصوصك الخاصة.
العثور على سلاسل فرعية باستخدام Bash Builtins
“الأقواس المزدوجة”
((...))
“يمكن استخدام اختبار مقارنة السلسلة في if
عبارات لتحديد ما إذا كانت سلسلة واحدة تحتوي على سلسلة أخرى.
انسخ هذا البرنامج النصي إلى محرر، ثم احفظه في ملف يسمى “double.sh”.
#!/bin/bashif (( "monkey" = *"key"* )); then
echo "key is in monkey"
else
echo "key is not in monkey"
fi
سوف تحتاج إلى جعل البرنامج النصي قابلاً للتنفيذ باستخدام chmod
الأمر. هذه خطوة مطلوبة دائمًا لجعل أي نص برمجي قابلاً للتنفيذ. ستحتاج إلى القيام بذلك في كل مرة تقوم فيها بإنشاء ملف نص برمجي. استبدل اسم النص البرمجي المناسب في كل حالة.
chmod +x double.sh
دعونا ننفذ البرنامج النصي.
./double.sh
يعمل هذا لأن علامة النجمة ” *
“يمثل أي تسلسل من الأحرف، بما في ذلك عدم وجود أحرف. إذا كان السلسلة الفرعية “key” موجودة داخل السلسلة المستهدفة، مع أو بدون أي أحرف أمامها أو خلفها، فسوف يعود الاختبار بالقيمة true.
في مثالنا، توجد أحرف أمام السلسلة الفرعية. ويتم مطابقتها بالعلامة النجمية الأولى. ولا توجد أحرف خلف السلسلة الفرعية، ولكن نظرًا لأن العلامة النجمية لا تتطابق أيضًا مع أي أحرف، فإن الاختبار لا يزال ناجحًا.
من أجل المرونة، يمكننا تعديل البرنامج النصي الخاص بنا للتعامل مع المتغيرات بدلاً من السلاسل الحرفية. هذا هو البرنامج النصي “double2.sh”.
#!/bin/bashstring="Monkey"
substring="key"
if (( $string = *$substring* )); then
echo "$substring was found in $string"
else
echo "$substring was not found in $string"
fi
دعونا نرى كيف سيتم ذلك.
./double2.sh
يعمل هذا بنفس الطريقة، مع ميزة أنه يمكننا استخدام أسماء المتغيرات بدلاً من السلاسل الحرفية. إن تحويل حلنا الصغير إلى دالة سيوفر أقصى قدر من المرونة.
هذا هو البرنامج النصي “double3.sh”.
#!/bin/bashshopt -s nocasematch
string="Monkey"
substring="Key"
capital="London"
check_substring ()
{
if (( $1 = *$2* )); then
echo "$2 was found in $1"
else
echo "$2 was not found in $1"
fi
}
check_substring "Monkey" "key"
check_substring $string $substring
check_substring $string "banana"
check_substring "Wales" $capital
نحن نطلق على check_substring
وظيفة باستخدام مزيج من المتغيرات والسلاسل الحرفية. لقد استخدمنا shopt
معها -s
(تعيين) خيار لتعيين nocasematch
، لجعل المطابقات غير حساسة لحالة الأحرف.
هكذا يتم تشغيله.
./double3.sh
يمكننا استخدام خدعة لف السلسلة الفرعية بعلامات النجمة في case
العبارات أيضًا. هذا هو “case.sh”.
#!/bin/bashshopt -s nocasematch
string="Wallaby"
substring="Wall"
case $string in
*$substring*)
echo "$substring was found in $string"
;;
*)
echo "Nothing matched: $string"
;;
esac
استخدام case
عبارات بدلا من عبارات طويلة جدا if
يمكن أن تجعل العبارات البرامج النصية أسهل في القراءة وتصحيح الأخطاء. إذا كنت بحاجة إلى التحقق مما إذا كانت السلسلة تحتوي على واحدة من العديد من السلاسل الفرعية المحتملة، case
سيكون البيان هو الخيار الأفضل.
./case.sh
تم العثور على السلسلة الفرعية.
العثور على سلاسل فرعية باستخدام grep
بخلاف عناصر Bash المضمنة، فإن أداة البحث عن النص الأولى التي ستصل إليها على الأرجح هي grep
.يمكننا استخدام grep
القدرة الفطرية للإنسان على البحث عن سلسلة داخل سلسلة للبحث عن سلاسل فرعية.
يُسمى هذا البرنامج النصي “subgrep.sh”.
#!/bin/bashstring="porridge pot"
substring="ridge"
if $(echo $string | grep -q $substring); then
echo "$substring was found in $string"
else
echo "$substring was not found in $string"
fi
يستخدم البرنامج النصي echo
لإرسال السلسلة إلى grep
، الذي يبحث عن السلسلة الفرعية. نحن نستخدم -q
(هادئ) خيار للتوقف grep
كتابة أي شيء إلى الإخراج القياسي.
إذا كانت نتيجة الأوامر الموجودة داخل الأقواس “(...)
“يساوي صفرًا، وهذا يعني أنه تم العثور على تطابق. لأن الصفر يساوي true
في باش، if
تم استيفاء البيان و then
تم تنفيذ البند.
دعونا نرى ما هو ناتجها.
./subgrep.sh
العثور على سلاسل فرعية باستخدام sed
يمكننا أن نستخدم sed
للعثور على سلسلة فرعية أيضًا.
By default, sed
prints all text that is fed into it. Using sed -n
prevents this. The only lines that are printed are matching lines. This expression will print any lines that match or contain the value of $substring.
"/$substring/p"
نحن نغذي القيمة $string
داخل sed
باستخدام إعادة التوجيه هنا، <<<
. يتم استخدام هذا لإعادة توجيه القيم إلى أمر في الغلاف الحالي. ولا يستدعي غلافًا فرعيًا بالطريقة التي يستدعيها الأنبوب.
الأول -n
هو الاختبار. سوف يعود true
إذا كان الناتج من sed
الأمر ليس صفرًا. الطريقة الوحيدة التي يتم بها إخراج الأمر هي sed
يمكن أن يكون غير صفر إذا تم العثور على خط مطابق. إذا كانت هذه هي الحالة، $substring
لا بد أن يكون قد تم العثور عليه في $string
.
هذا هو "subsed.sh."
#!/bin/bashstring="Sweden"
substring="eden"
if ( -n "$(sed -n "/$substring/p" <<< $string)" ); then
echo "$substring was found in $string"
else
echo "$substring was not found in $string"
fi
نحصل على الاستجابة المتوقعة عندما نقوم بتشغيل البرنامج النصي.
./subsed.sh
يمكننا اختبار منطق البرنامج النصي عن طريق تحرير قيمة $substring
حتى تفشل المقارنة.
./subsed.sh
توقف عن البحث، لقد وجدته
يمكن لأدوات أخرى العثور على سلاسل فرعية، مثل awk
و Perl
لكن حالة استخدام بسيطة مثل العثور على سلسلة فرعية لا تبرر وظائفها الإضافية ولا التعقيد المضاف. على وجه الخصوص، يعد استخدام عناصر Bash المضمنة للبحث عن سلاسل فرعية سريعًا وبسيطًا ولا يتطلب أدوات خارجية.