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


Answers

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

string='My string';

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

لدي سلسلة في 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

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




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

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



لقد وجدت أنني بحاجة إلى هذه الوظيفة بشكل متكرر ، لذلك فأنا أستخدم دالة 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 الداخلية ، حيث يتم إنشاء عملية منفصلة واحدة (أو اثنتين) وربطها عبر الأنابيب.




أنا استخدم هذه الوظيفة (تبعية واحدة غير مدرجة ولكن واضحة). يمر الاختبارات المبينة أدناه. إذا كانت الدالة تقوم بإرجاع قيمة> 0 ثم تم العثور على السلسلة. يمكنك بسهولة العودة 1 أو 0 بدلاً من ذلك.

function str_instr {
   # Return position of ```str``` within ```string```.
   # >>> str_instr "str" "string"
   # str: String to search for.
   # string: String to search.
   typeset str string x
   # Behavior here is not the same in bash vs ksh unless we escape special characters.
   str="$(str_escape_special_characters "${1}")"
   string="${2}"
   x="${string%%$str*}"
   if [[ "${x}" != "${string}" ]]; then
      echo "${#x} + 1" | bc -l
   else
      echo 0
   fi
}

function test_str_instr {
   str_instr "(" "'foo@host (dev,web)'" | assert_eq 11
   str_instr ")" "'foo@host (dev,web)'" | assert_eq 19
   str_instr "[" "'foo@host [dev,web]'" | assert_eq 11
   str_instr "]" "'foo@host [dev,web]'" | assert_eq 19
   str_instr "a" "abc" | assert_eq 1
   str_instr "z" "abc" | assert_eq 0
   str_instr "Eggs" "Green Eggs And Ham" | assert_eq 7
   str_instr "a" "" | assert_eq 0
   str_instr "" "" | assert_eq 0
   str_instr " " "Green Eggs" | assert_eq 6
   str_instr " " " Green "  | assert_eq 1
}



grep -q مفيد لهذا الغرض.

نفس الشيء باستخدام awk :

string="unix-bash 2389"
character="@"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

انتاج:

غير معثور عليه

string="unix-bash 2389"
character="-"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

انتاج:

وجدت

المصدر الأصلي: http://unstableme.blogspot.com/2008/06/bash-search-letter-in-string-awk.html




واحد هو:

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



بلدي .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



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

نظرًا لوجود العديد من الإجابات باستخدام ميزات 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="$@"
    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



الإجابة المقبولة هي الأفضل ، ولكن نظرًا لوجود أكثر من طريقة لفعل ذلك ، فإليك الحل الآخر:

if [ "$string" != "${string/foo/}" ]; then
    echo "It's there!"
fi

${var/search/replace} هو $var مع استبدال المثيل الأول search عن replace ، إذا تم العثور عليه (لا يغير $var ). إذا حاولت استبدال foo من لا شيء ، وتغيرت السلسلة ، فمن الواضح أنه تم العثور على foo .




Related