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





bash substring (17)


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

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

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




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

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

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




وماذا عن هذا:

text="   <tag>bmnmn</tag>  "
if [[ "$text" =~ "<tag>" ]]; then
   echo "matched"
else
   echo "not matched"
fi



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



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




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



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

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

/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! القاعدة القديمة حول استخدام المرافق الخارجية دون الحاجة إلى حقيقة.




كما ذكر بول في مقارنة أدائه:

if echo "abcdefg" | grep -q "bcdef"; then
    echo "String contains is true."
else
    echo "String contains is not true."
fi

هذا متوافق مع POSIX مثل السلسلة "case" $ "in" التي يقدمها Marcus ، ولكن أسهل قليلاً من قراءة إجابة الحالة. لاحظ أيضًا أن هذا سيكون أبطأ بكثير من استخدام بيان الحالة ، كما أشار بول ، لا تستخدمه في حلقة.




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

string='My string';

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



واحد هو:

[ $(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).




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

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

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




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

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



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

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



محاولة oobash هو مكتبة سلسلة على غرار OO لباش 4. لديها دعم لعلامات تغير في اللغة الألمانية. هو مكتوب في باش. تتوفر العديد من الوظائف: -base64Decode ، -base64Encode ، -capitalize ، -center ، -charAt ، -concat ، -count ، -endsWith ، -equals ، -equalsIgnoreCase ، -reverse ، -hashCode ، -indexOf ، -isAlnum ، -isAlnum ، -isAlpha ، -isAscii ، -isDigit ، -isEmpty ، -isHexDigit ، -isLowerCase ، -isSpace ، -isPrintable ، -isUpperCase ، -isVisible ، -lastIndexOf ، -length ، -matches ، -replaceAll ، -replaceFirst ، -startsWith ، -substring ، -swapCase ، -toLowerCase ، -toString ، -toUpperCase ، -trim ، and -zfill .

انظر إلى المثال الذي يحتوي على:

[Desktop]$ String a testXccc                                                  
[Desktop]$ a.contains tX                   
true                                                           
[Desktop]$ a.contains XtX      
false      

oobash متاح في Sourceforge.net .




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

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

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



توفر الجوافة حلًا أوتوماتيكيًا أقصر بكثير في حالة ما إذا كان مصدر المدخلات يأتي من مورد الفئات (الذي يبدو مهمة شائعة):

String content = Files.asCharSource(new File("robots.txt"), StandardCharsets.UTF_8).read();
byte[] data = Files.asByteSource(new File("favicon.ico")).read();

أو

String content = Files.toString(new File("robots.txt"), StandardCharsets.UTF_8);
byte[] data = Files.toByteArray(new File("favicon.ico"));

هناك أيضًا مفهوم عام عن ByteSource و CharSource الذي CharSource برفق بفتح وغلق البث.

لذلك ، على سبيل المثال ، بدلاً من فتح ملف صغير بشكل واضح لقراءة محتوياته:

public String read (InputStream is) {
    byte next = is.read();
    return next == -1 ? "" : next + read(is); // Recursive part: reads next byte recursively
}

أو فقط

 String content = Files.toString(new File("robots.txt"), StandardCharsets.UTF_8); byte[] data = Files.toByteArray(new File("favicon.ico")); 




string bash substring