Reputation: 854
I wanna test whether a string has "substring". Most answers online is based on Bash. I tried
if [ $string == "*substring*" ]
which was not working. Currently
if echo ${string} | grep -q "substring"
worked. Is there any other better way.
Upvotes: 7
Views: 5133
Reputation: 439317
In a POSIX-features only shell you won't be able to do general pattern or regex matching inside a conditional without the help of an external utility.
That said:
Kenster's helpful answer shows how to use the branches of a case ... esac
statement for pattern matching.
Inian's helpful answer shows how to match indirectly inside a conditional, using patterns as part of parameter expansions.
Your own grep
approach is certainly an option, though you should double-quote ${string}
:
if echo "${string}" | grep -q "substring"; ...
A slightly more efficient way is to use the expr
utility, but note that per POSIX it is limited to BREs (basic regular expressions), which are limited:
string='This text contains the word "substring".'
if expr "$string" : ".*substring" >/dev/null; then echo "matched"; fi
Note that the regex - the 3rd operand - is implicitly anchored at the start of the input, hence the need for .*
.
>/dev/null
suppresses expr
's default output, which is the length of the matched string in this case. (If nothing matches, the output is 0
, and the exit code is set to 1
).
Upvotes: 6
Reputation: 25439
If you're just testing for substrings (or anything that can be matched using filename wildcards) you can use case
:
#!/bin/sh
while read line; do
case "$line" in
*foo*) echo "$line" contains foo ;;
*bar*) echo "$line" contains bar ;;
*) echo "$line" isnt special ;;
esac
done
$ ./testit.sh
food
food contains foo
ironbar
ironbar contains bar
bazic
bazic isnt special
foobar
foobar contains foo
This is basic Bourne shell functionality. It doesn't require any external programs, it's not bash-specific, and it predates POSIX. So it should be pretty portable.
Upvotes: 3
Reputation: 85790
Using POSIX compliant parameter-expansion and with the classic test-command.
#!/bin/sh
substring=ab
string=abc
if [ "$string" != "${string%"$substring"*}" ]; then
echo "$substring present in $string"
fi
(or) explicitly using the test
operator as
if test "$string" != "${string%$substring*}" ; then
Upvotes: 10
Reputation: 114440
Short answer is no, not if you are trying to use vanilla sh, without Bash extensions. On many modern systems, /bin/sh
is actually a link to /bin/bash
, which provides a superset of sh
's functionality (for the most part). Your original attempt would have worked with Bash's builtin [[
extended test command: http://mywiki.wooledge.org/BashFAQ/031
Upvotes: 0