باش، اندفاعة ومقارنة سلسلة
-
11-09-2019 - |
سؤال
أحاول مقارنة خطين في نص شل بسيط. كنت أستخدم /bin/sh
بدلا من /bin/bash
, وبعد ساعات لا تحصى من التصحيح، فإنه يتضح أن SH (وهو داش فعلا) لا يمكن التعامل مع هذه الكتلة من التعليمات البرمجية:
if [ "$var" == "string" ]
then
do something
fi
ما هي طريقة محمولة لمقارنة السلاسل باستخدام /bin/sh
ب أعلم أنني أستطيع أن أفعل دائما عكس ذلك باستخدام! =، لكنني أتساءل عن طريقة نظافة محمولة.
المحلول
dash
هي قذيفة بوسيكس صارمة للغاية، إذا كان يعمل في dash
من المؤكد أنه سيعمل في قذيفة بوسيكس أخرى.
يحاول:
if [ "$var" = "string" ]
then
some_command
fi
نصائح أخرى
لماذا هناك احتمال أن يتم تشغيل البرنامج النصي الخاص بك من خلال قذيفة "خاطئة"؟ أعتقد أنك يمكن أن تجعل ذلك متطلبا مسبقا لمنتجك باستخدام خط Sh-Bang القياسي في الجزء العلوي من البرنامج النصي الخاص بك:
#!/bin/bash
حتى لو كان المستخدم الاستخدامات قذيفة مختلفة، والأقذائف الأخرى لا تزال هناك عموما، وإذا لم يكن كذلك، فإن ببساطة يشكو وذكر أنهم ما قبل الريك.
بالضبط بنفس الطريقة التي يمكن أن تكون بها مستوى نواة معين، أو وجود AWK، ما قبل الريك.
لسؤالك المحدد، أعتقد sh
و bash
السماح للأحد "=" لاستخدامها في مقارنات السلسلة - وهذا هو سلوك Posix:
if [ "a" = "a" ] ; then
echo yes
fi
yes
يستخدم =
بدلا من ==
. وبعد يتم التعامل مع المقارنات عن طريق الاختبار (1). /usr/bin/[
هو عادة رابط ل /usr/bin/test
وبعد الفرق الوحيد هو أنه إذا كنت تستخدم [
في نص شل، ]
مطلوب كذلك.
لاحظ أن باش لديه مدمج test
/[
, ، لذلك لا يستخدم في الواقع /usr/bin/test
.
هذه الإجابات المنشورة بالفعل هي بالتأكيد صحيحة، ولكن قد يكون من المفيد ملاحظة أن توسع المعلمة أحيانا يمكن أن يخدم نفس الغرض مع بعض المرونة الإضافية.
% p() { printf 'notvar = %b\n' "${notvar##"${string1}"}${string2}" ; }
% string1='some stuff about things\c'
% string2='some different stuff maybe'
% notvar="$string1" p
> 'some different stuff maybe'
% notvar="$string2" p
> 'some stuff about things'
انقر فوق "موافق"، وبالتالي فإن ما ورد أعلاه غير مفيد للغاية كما هو الحال، بل يعتبر أيضا أنه يمكنك استخدام الأساليب المماثلة لمتغيرات الاختبار في المستندات الواردة هنا، المهام المتغيرة عبر الإنترنت إذا لزم الأمر (إلى درجة ...)، أو حتى فقط كوسيلة أقصر (وأسرع!) لكتابة البيان الأول الخاص بك.
[ ! "${var##"string"}" ] && _MATCH || _NOMATCH
او حتى...
[ ${#var#*"${s=string}"} -lt ${#var} ] && _SUB_STRING_TEST=TRUE
ربما حتى ...
% p() { printf '%s is %s of %s' "$2" "${var_chk-not}" "$1"
> }<<HEREDOC
> ${in="${1##*"${2}"*}"}
> ${in:-
> ${in="${1##"${2}"}"}
> ${in:-${var_chk=all}
> ${var_chk=some}
> }
> HEREDOC
%
يمكنك استخدام AWK
awk 'BEGIN{
string1="test"
string2="tes1t"
if(s1==s2){
print "same string"
}else{
print "not same"
}
}'