string - سلسلة تحتوي على باش




bash substring (14)

إجابة متوافقة

نظرًا لوجود العديد من الإجابات باستخدام ميزات Bash الخاصة ، فهناك طريقة للعمل تحت الأصداف ذات busybox ، مثل busybox :

[ -z "${string##*$reqsubstr*}" ]

في الممارسة العملية ، قد يعطي هذا:

string='echo "My string"'
for reqsubstr in 'o "M' 'alt' 'str';do
  if [ -z "${string##*$reqsubstr*}" ] ;then
      echo "String '$string' contain substring: '$reqsubstr'."
    else
      echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
  done

تم اختبار ذلك تحت bash و dash و ksh و ash (busybox) وكانت النتيجة دائمًا:

String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.

في وظيفة واحدة

كما تم السؤال عنEeroAaltonen هنا هو نسخة من نفس العرض التجريبي ، تم اختباره تحت نفس القذائف:

myfunc() {
    reqsubstr="$1"
    shift
    string="[email protected]"
    if [ -z "${string##*$reqsubstr*}" ] ;then
        echo "String '$string' contain substring: '$reqsubstr'.";
      else
        echo "String '$string' don't contain substring: '$reqsubstr'." 
    fi
}

ثم:

$ myfunc 'o "M' 'echo "My String"'
String 'echo "My String"' contain substring 'o "M'.

$ myfunc 'alt' 'echo "My String"'
String 'echo "My String"' don't contain substring 'alt'.

ملاحظة: يجب عليك الهروب أو وضع علامات اقتباس مزدوجة و / أو علامات اقتباس مزدوجة:

$ myfunc 'o "M' echo "My String"
String 'echo My String' don't contain substring: 'o "M'.

$ myfunc 'o "M' echo \"My String\"
String 'echo "My String"' contain substring: 'o "M'.

وظيفة بسيطة

تم اختبار ذلك ضمن busybox ، dash ، وبالطبع bash :

stringContain() { [ -z "${2##*$1*}" ]; }

هذا كل ما لدي أيها الناس!

ثم الآن:

$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
no
$ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
yes

... أو إذا كانت السلسلة المقدمة فارغة ، كما أشارSjlver ، فستصبح الوظيفة:

stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }

أو كما اقترحه تعليق Adrian Günter ، وتجنب switche -o :

stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ] ;} ; }

مع سلاسل فارغة:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

لدي سلسلة في Bash:

string="My string"

كيف يمكنني اختبار إذا كان يحتوي على سلسلة أخرى؟

if [ $string ?? 'foo' ]; then
  echo "It's there!"
fi

اين ?? هو المشغل الخاص بي غير معروف. هل أستخدم الصدى و grep ؟

if echo "$string" | grep 'foo'; then
  echo "It's there!"
fi

هذا يبدو خرقاء بعض الشيء.


أنا أحب سيد.

substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1

تحرير ، المنطق:

  • استخدم sed لإزالة مثيل من السلسلة من السلسلة

  • إذا اختلفت السلسلة الجديدة من السلسلة القديمة ، توجد سلسلة فرعية


إذا كنت تفضل نهج regex:

string='My string';

if [[ $string =~ .*My.* ]]
then
   echo "It's there!"
fi

إذاً هناك الكثير من الحلول المفيدة للسؤال - لكن الأسرع / يستخدم أقل الموارد؟

الاختبارات المتكررة باستخدام هذا الإطار:

/usr/bin/time bash -c 'a=two;b=onetwothree; x=100000; while [ $x -gt 0 ]; do TEST ; x=$(($x-1)); done'

استبدال الاختبار في كل مرة:

[[ $b =~ $a ]]           2.92user 0.06system 0:02.99elapsed 99%CPU

[ "${b/$a//}" = "$b" ]   3.16user 0.07system 0:03.25elapsed 99%CPU

[[ $b == *$a* ]]         1.85user 0.04system 0:01.90elapsed 99%CPU

case $b in *$a):;;esac   1.80user 0.02system 0:01.83elapsed 99%CPU

doContain $a $b          4.27user 0.11system 0:04.41elapsed 99%CPU

(كان doContain في إجابة F. Houri)

وللضحكات:

echo $b|grep -q $a       12.68user 30.86system 3:42.40elapsed 19%CPU !ouch!

لذا فإن خيار الاستبدال البسيط سيفوز سواء في اختبار ممتد أو في حالة. هذه القضية محمولة.

من الضروري التنبؤ بالأنابيب إلى 100000 greps! القاعدة القديمة حول استخدام المرافق الخارجية دون الحاجة إلى حقيقة.


بلدي .bash_profile وكيف استخدمت grep إذا تضمن PATH my 2 bin dirs ، لا إلحاق بها

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

U=~/.local.bin:~/bin

if ! echo "$PATH" | grep -q "home"; then
    export PATH=$PATH:${U}   
fi

تطابق الكلمة الدقيق:

string='My long string'
exactSearch='long'

if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2>&1
  then
    echo "It's there"
  fi

لست متأكدًا من استخدام بيان if ، ولكن يمكنك الحصول على تأثير مماثل مع بيان الحالة:

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

لقد وجدت أنني بحاجة إلى هذه الوظيفة بشكل متكرر ، لذلك فأنا أستخدم دالة shell محلية الصنع في ملفي .bashrc هذا مما يسمح لي بإعادة استخدامه كلما احتجت إلى ذلك ، مع اسم يسهل تذكره:

function stringinstring()
{
    case "$2" in 
       *"$1"*)
          return 0
       ;;
    esac   
    return 1
}

لاختبار ما إذا كان $string1 (على سبيل المثال ، abc ) موجودًا في $string2 (على سبيل المثال ، 123abcABC ) ، فأنا بحاجة فقط إلى تشغيل stringinstring "$string1" "$string2" والتحقق من قيمة الإرجاع ، على سبيل المثال

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO

هذا يعمل أيضا:

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

والاختبار السلبي هو:

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

أفترض أن هذا النمط هو كلاسيكي أكثر قليلاً - أقل اعتماداً على ميزات Bash shell.

الوسيطة -- نقي POSIX paranoia ، تستخدم للحماية ضد سلاسل الإدخال المشابهة للخيارات ، مثل --abc أو -a .

ملاحظة: في حلقة ضيقة ، سيكون هذا الرمز أبطأ بكثير من استخدام ميزات Bash shell الداخلية ، حيث يتم إنشاء عملية منفصلة واحدة (أو اثنتين) وربطها عبر الأنابيب.


واحد هو:

[ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'

يجب عليك أن تتذكر أن برنامج shell shell أقل من لغة وأكثر من مجموعة من الأوامر. بشكل غريزي تعتقد أن هذه "اللغة" تتطلب منك أن تتبع if مع [ أو [[ . كلاهما مجرد أوامر تقوم بإرجاع حالة خروج تشير إلى النجاح أو الفشل (تمامًا مثل كل أمر آخر). لهذا السبب grep ، وليس [ الأمر.

فقط افعل:

if grep -q foo <<<"$string"; then
    echo "It's there"
fi

الآن ، أنت تفكر فيما if تختبر حالة الخروج للأمر الذي يتبعها (كاملة مع منقوطة). لماذا لا تعيد النظر في مصدر السلسلة التي تختبرها؟

## Instead of this
filetype="$(file -b "$1")"
if grep -q "tar archive" <<<"$filetype"; then
#...

## Simply do this
if file -b "$1" | grep -q "tar archive"; then
#...

الخيار -q يجعل grep لا يخرج أي شيء ، لأننا نريد فقط رمز الإرجاع. <<< يجعل shell يوسع الكلمة التالية ويستخدمها كإدخال للأمر ، نسخة من سطر واحد من الوثيقة << هنا (لست متأكدا ما إذا كان هذا قياسي أو bashism).


يمكنك استخدام إجابة ماركوس (* أحرف البدل) خارج بيان الحالة أيضًا ، إذا كنت تستخدم قوسين:

string='My long string'
if [[ $string = *"My long"* ]]; then
  echo "It's there!"
fi

لاحظ أنه يجب وضع المسافات في سلسلة الإبرة بين علامتي اقتباس مزدوجتين ، ويجب أن تكون أحرف البدل في الخارج.


كانت هذه الإجابة على هي الوحيدة التي احتوت المساحة والعبارات الجانبية:

# For null cmd arguments checking   
to_check=' -t'
space_n_dash_chars=' -'
[[ $to_check == *"$space_n_dash_chars"* ]] && echo found

[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"




substring