views:

23796

answers:

10

Using bash, I have a string:

string=`echo My string`

How can I test if it contains another string?

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

Where ?? is my unknown operator. Do I use echo and grep?

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

That looks a bit clumsy.

+6  A: 

I am not sure about using an if statement, but you can get a similar effect with a case statement:

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac
Marcus Griep
+1  A: 

The other way is expr match or its shortened version:

str=this_is_my_string
if [ `expr match "$str" ".*my.*"` != "0" ]; then
  echo "there";
fi;

However, this is using regular expressions, not a substring match.

The shortened version is

expr "$variable" : 'regex'
daveb
+28  A: 

You can use Marcus's answer (* wildcards) outside a case statement, too, if you use double brackets:

string='My string';

if [[ $string == *My* ]]
then
  echo "It's there!";
fi
Adam Bellaire
Also note that you can reverse the comparison by just switching to != in the test. Thanks for the answer!
Quinn Taylor
+3  A: 

The accepted answer is best, but since there's more than one way to do it, here's another solution:

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

${var/search/replace} is $var with the first instance of search replaced by replace, if it's found (it doesn't change $var). If you try to replace foo by nothing, and the string has changed, then obviously foo was found.

ephemient
+5  A: 

If you prefer the regex approach:

string='My string';

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

I'd use grep, and not use the [ command, just do

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

The -q option makes grep not output anything, as we only want the return code. <<< makes the shell expand the next word and use it as the input to the command, a one-line version of the << here document (I'm not sure whether this is standard or a bashism).

Mark Baker
A: 

grep -q is useful for this purpose, thanks.

The same using awk


$ string="unix-bash 2389"
$ character="@"

$ echo $string | awk -vc="$character" '{if(gsub(c,"")) print "Found";else print "Not Found"}'

Not Found

$ character="-"

$ echo $string | awk -vc="$character" '{if(gsub(c,"")) print "Found";else print "Not Found"}'

Found

http://unstableme.blogspot.com/2008/06/bash-search-letter-in-string-awk.html

// Jadu Saikia

A: 

How about this:

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

Regards, Stefan

=~ is for regexp matching, hence too powerful for the OP's purpose.
Georgi Kirilov
A: 

Try oobash it is an OO-style string library for bash 4. It has support for German umlauts. It is written in bash. Many functions are available: -base64Decode, -base64Encode, -capitalize, -center, -charAt, -concat, -contains, -count, -endsWith, -equals, -equalsIgnoreCase, -reverse, -hashCode, -indexOf, -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.

Look at the contains example:

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

andreas
A: 

ephemient's solution above:

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

is useful when using BusyBox's shell ash. The accepted solution does not work with BusyBox because some bash's regular expressions are not implemented.

TPoschel