This is another possible POSIX solution based on this answer, but making it work with special characters, like []*
. This is achieved surrounding the substring
variable with double quotes.
This is an alternative implementation of this other answer on another thread using only shell builtins. If string
is empty the last test
would give a false positive, hence we need to test whether substring
is empty as well in that case.
#!/bin/sh
# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
string="$1"
substring="$2"
test -n "$string" || test -z "$substring" && test -z "${string##*"$substring"*}"
}
Or one-liner:
contains() { test -n "$1" || test -z "$2" && test -z "${1##*"$2"*}"; }
Nevertheless, a solution with case
like this other answer looks simpler and less error prone.
#!/bin/sh
contains() {
string="$1"
substring="$2"
case "$string" in
*"$substring"*) true ;;
*) false ;;
esac
}
Or one-liner:
contains() { case "$1" in *"$2"*) true ;; *) false ;; esac }
For the tests:
contains "abcd" "e" || echo "abcd does not contain e"
contains "abcd" "ab" && echo "abcd contains ab"
contains "abcd" "bc" && echo "abcd contains bc"
contains "abcd" "cd" && echo "abcd contains cd"
contains "abcd" "abcd" && echo "abcd contains abcd"
contains "" "" && echo "empty string contains empty string"
contains "a" "" && echo "a contains empty string"
contains "" "a" || echo "empty string does not contain a"
contains "abcd efgh" "cd ef" && echo "abcd efgh contains cd ef"
contains "abcd efgh" " " && echo "abcd efgh contains a space"
contains "abcd [efg] hij" "[efg]" && echo "abcd [efg] hij contains [efg]"
contains "abcd [efg] hij" "[effg]" || echo "abcd [efg] hij does not contain [effg]"
contains "abcd *efg* hij" "*efg*" && echo "abcd *efg* hij contains *efg*"
contains "abcd *efg* hij" "d *efg* h" && echo "abcd *efg* hij contains d *efg* h"
contains "abcd *efg* hij" "*effg*" || echo "abcd *efg* hij does not contain *effg*"