ChatGPT解决这个技术问题 Extra ChatGPT

How to check if a string contains a substring in Bash

I have a string in Bash:

string="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.

Hi, if empty strings are false, why do you consider it clumsy? It was the only way that worked for me, despite the proposed solutions.
You can use the expr command here
Here's one for posix shells: stackoverflow.com/questions/2829613/…
Please use $needle in a $haystack idiom in your example. It's much easier to read and understand.

m
michael-slx

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

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

Note that spaces in the needle string need to be placed between double quotes, and the * wildcards should be outside. Also note that a simple comparison operator is used (i.e. ==), not the regex operator =~.


Also note that you can reverse the comparison by just switching to != in the test. Thanks for the answer!
Hmm, with this exact code, I get [[: not found. Any idea what's wrong? I'm using GNU bash, version 4.1.5(1), on Ubuntu.
@Jonik: You may be missing the shebang or have it as #!/bin/sh. Try #!/bin/bash instead.
A
Asclepius

If you prefer the regex approach:

string='My string';

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

Had to replace an egrep regex in a bash script, this worked perfectly!
The =~ operator already searches the whole string for a match; the .*'s here are extraneous. Also, quotes are generally preferable to backslashes: [[ $string =~ "My s" ]]
@bukzor Quotes stopped working here as of Bash 3.2+: tiswww.case.edu/php/chet/bash/FAQ E14). It's probably best to assign to a variable (using quotes), then compare. Like this: re="My s"; if [[ $string =~ $re ]]
Test if it does NOT contain a string: if [[ ! "abc" =~ "d" ]] is true.
M
Marcus Griep

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

This is probably the best solution since it is portable to posix shells. (a.k.a. no bashisms)
@technosaurus I find it rather odd to criticize "bashism" in a question that has only bash tag :)
@P.P. It's not so much a criticism as the preference of a more universal solution over a more limited one. Please consider that, years later, people (like me) will stop by to look for this answer and may be pleased to find one that's useful in a wider scope than the original question. As they say in the Open Source world: "choice is good!"
@technosaurus, FWIW [[ $string == *foo* ]] also works in some POSIX compliant sh versions (e.g. /usr/xpg4/bin/sh on Solaris 10) and ksh (>= 88)
F
F. Hauri - Give Up GitHub

stringContain variants (compatible or case independent)

As these Stack Overflow answers tell mostly about Bash, I've posted a case independent Bash function at the very bottom of this post...

Anyway, there is my

Compatible answer

As there are already a lot of answers using Bash-specific features, there is a way working under poorer-featured shells, like BusyBox:

[ -z "${string##*$reqsubstr*}" ]

In practice, this could give:

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

This was tested under Bash, Dash, KornShell (ksh) and ash (BusyBox), and the result is always:

String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.

Into one function

As asked by @EeroAaltonen here is a version of the same demo, tested under the same shells:

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
}

Then:

$ 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'.

Notice: you have to escape or double enclose quotes and/or double quotes:

$ 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'.

Simple function

This was tested under BusyBox, Dash, and, of course Bash:

stringContain() { [ -z "${2##*$1*}" ]; }

Then now:

$ 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

... Or if the submitted string could be empty, as pointed out by @Sjlver, the function would become:

stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }

or as suggested by Adrian Günter's comment, avoiding -o switches:

stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ];};}

Final (simple) function:

And inverting the tests to make them potentially quicker:

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}

With empty strings:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

Case independent (Bash only!)

For testing strings without care of case, simply convert each string to lower case:

stringContain() {
    local _lc=${2,,}
    [ -z "$1" ] || { [ -z "${_lc##*${1,,}*}" ] && [ -n "$2" ] ;} ;}

Check:

stringContain 'o "M3' 'echo "my string"' && echo yes || echo no
no
stringContain 'o "My' 'echo "my string"' && echo yes || echo no
yes
if stringContain '' ''; then echo yes; else echo no; fi
yes
if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

This would be even better, if you can figure out some way to put that to a function.
@EeroAaltonen How do you find my (new added) function?
I know! find . -name "*" | xargs grep "myfunc" 2> /dev/null
@F.Hauri Sorry, was a joke to your comment to EuroAaltonen The find command has absolutely nothing to do with the question posted on this thread.
This is wonderful because it's so compatible. One bug, though: It does not work if the haystack string is empty. The correct version would be string_contains() { [ -z "${2##*$1*}" ] && [ -n "$2" -o -z "$1" ]; } A final thought: does the empty string contain the empty string? The version above things yes (because of the -o -z "$1" part).
P
Peter Mortensen

You should remember that shell scripting is less of a language and more of a collection of commands. Instinctively you think that this "language" requires you to follow an if with a [ or a [[. Both of those are just commands that return an exit status indicating success or failure (just like every other command). For that reason I'd use grep, and not the [ command.

Just do:

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

Now that you are thinking of if as testing the exit status of the command that follows it (complete with semi-colon), why not reconsider the source of the string you are testing?

## 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
#...

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).


they are called here strings (3.6.7) I believe it is bashism
one can also use Process Substitution if grep -q foo <(echo somefoothing); then
Note that echo is unportable, if you're passing a variable, use printf '%s' "$string instead.
The cost of this is very expensive: doing grep -q foo <<<"$mystring" implie 1 fork and is bashism and echo $mystring | grep -q foo implie 2 forks (one for the pipe and the second for running /path/to/grep)
@BrunoBronosky echo without flags might still have unexpected portability problems if the argument string contains backslash sequences. echo "nope\c" is expected on some platforms to work like echo -e "nope" on some others. printf '%s' "nope" vs printf '%s\n' 'nope\c'
Z
Zombo

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 is 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'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.
the inequality of difference. Pretty weird thought! I love it
unless your string is 'foo' though
@hanshenrik You're comparing $XDG_CURRENT_DESKTOP to $string. The expression you want is if [ "$XDG_CURRENT_DESKTOP" != "${XDG_CURRENT_DESKTOP/GNOME/}" ]; then echo MATCHES GNOME; fi
@venimus yeah, "x$string" != "x${string/foo/}" is better.
P
Peter Mortensen

So there are lots of useful solutions to the question - but which is fastest / uses the fewest resources?

Repeated tests using this frame:

/usr/bin/time bash -c 'a=two;b=onetwothree; x=100000; while [ $x -gt 0 ]; do TEST ; x=$(($x-1)); done'

Replacing TEST each time:

[[ $b =~ $a ]]           2.92 user 0.06 system 0:02.99 elapsed 99% CPU

[ "${b/$a//}" = "$b" ]   3.16 user 0.07 system 0:03.25 elapsed 99% CPU

[[ $b == *$a* ]]         1.85 user 0.04 system 0:01.90 elapsed 99% CPU

case $b in *$a):;;esac   1.80 user 0.02 system 0:01.83 elapsed 99% CPU

doContain $a $b          4.27 user 0.11 system 0:04.41 elapsed 99%CPU

(doContain was in F. Houri's answer)

And for giggles:

echo $b|grep -q $a       12.68 user 30.86 system 3:42.40 elapsed 19% CPU !ouch!

So the simple substitution option predictably wins whether in an extended test or a case. The case is portable.

Piping out to 100000 greps is predictably painful! The old rule about using external utilities without need holds true.


Neat benchmark. Convinced me to use [[ $b == *$a* ]].
If I'm reading this correctly, case wins with the smallest overall time consumption. You are missing an asterisk after $b in *$a though. I get slightly faster results for [[ $b == *$a* ]] than for case with the bug corrected, but it could depend on other factors too, of course.
ideone.com/5roEVt has my experiment with some additional bugs fixed and tests for a different scenario (where the string is actually not present in the longer string). Results are largely similar; [[ $b == *$a* ]] is quick and case is almost as quick (and pleasantly POSIX-compatible).
The conditional expression [[ $b == *$a* ]] and the case statement case $b in *$a):;;esac are not equivalent in a no-match condition. Swapping $a and $b results in exit code 1 for the conditional expression [[ and exit code 0 for the case statement. As per help case: Exit Status: Returns the status of the last command executed. The return status is zero if no pattern is matched, which is probably not the expected behavior. To return 1 in the no match condition, it should be: case $b in *$a*):;; *) false ;; esac
k
kevinarpe

This also works:

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

And the negative test is:

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

I suppose this style is a bit more classic -- less dependent upon features of Bash shell.

The -- argument is pure POSIX paranoia, used to protected against input strings similar to options, such as --abc or -a.

Note: In a tight loop this code will be much slower than using internal Bash shell features, as one (or two) separate processes will be created and connected via pipes.


...but the OP doesn't say which version of bash; e.g., older bash's (such as solaris frequently has) may not include these newer bash features. (I've run into this exact problem (bash pattern matching not implemented) on solaris w/ bash 2.0)
echo is unportable, you should be using printf '%s' "$haystack instead.
Nope, just avoid echo altogether for anything but literal text without escapes that doesn't start with a -. It may work for you, but it's not portable. Even bash's echo will behave differently depending on whether the xpg_echo option is set. P.S.: I forgot to close the double quote in my previous comment.
@kevinarpe I'm not sure, -- is not listed in the POSIX spec for printf, but you should use printf '%s' "$anything" anyway, to avoid issues if $anything contains a % character.
@kevinarpe Based on that, it probably is.
P
Peter Mortensen

Bash 4+ examples. Note: not using quotes will cause issues when words contain spaces, etc. Always quote in Bash, IMO.

Here are some examples Bash 4+:

Example 1, check for 'yes' in string (case insensitive):

    if [[ "${str,,}" == *"yes"* ]] ;then

Example 2, check for 'yes' in string (case insensitive):

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

Example 3, check for 'yes' in string (case sensitive):

     if [[ "${str}" == *"yes"* ]] ;then

Example 4, check for 'yes' in string (case sensitive):

     if [[ "${str}" =~ "yes" ]] ;then

Example 5, exact match (case sensitive):

     if [[ "${str}" == "yes" ]] ;then

Example 6, exact match (case insensitive):

     if [[ "${str,,}" == "yes" ]] ;then

Example 7, exact match:

     if [ "$a" = "$b" ] ;then

Example 8, wildcard match .ext (case insensitive):

     if echo "$a" | egrep -iq "\.(mp[3-4]|txt|css|jpg|png)" ; then

Enjoy.


Aaaah - I only understood it after I found out that the two commas in ${str,,} convert $str to lower case. Great solutions / great list!
P
Peter Mortensen

As Paul mentioned in his performance comparison:

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

This is POSIX compliant like the 'case "$string" in' the answer provided by Marcus, but it is slightly easier to read than the case statement answer. Also note that this will be much much slower than using a case statement. As Paul pointed out, don't use it in a loop.


b
bn.

How about this:

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

=~ is for regexp matching, hence too powerful for the OP's purpose.
J
Jahid
[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"

I will add that the echo "Couldn't find statement at the end is a nice trick to return 0 exit statuses for these matching commands.
@nicodjimenez you can not target exit status any more with this solution. Exit status is swallowed up by the status messages ...
That's exactly what I meant... If you don't have || echo "Couldn't find" then you will return an error exit status if there is no match, which you might not want if you're running a CI pipeline for example where you want all commands to return non error exit statuses
P
Peter Mortensen

This Stack Overflow answer was the only one to trap space and dash characters:

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

It is an answer to this same question.
P
Piotr Henryk Dabrowski

Accepted answer is correct but it is hard to read and understand. For problems related to searching you should always use the $needle in a $haystack idiom. Since its suggested edit queue is full, I post this:

haystack='There are needles here.'
if [[ "$haystack" == *"needle"* ]]; then
    echo "It's there!"
fi

P
Peter Mortensen

One is:

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

expr is one of those swiss-army-knife utilities that can usually do whatever it is you need to do, once you figure out how to do it, but once implemented, you can never remember why or how it's doing what it's doing, so you never touch it again, and hope that it never stops doing what it's doing.
@AloisMahdal I never down-voted, I'm just postulating on why downvotes were given. A cautionary comment. I do use expr, on rare occasion, when portability prevents using bash (eg., inconsistent behavior across older versions), tr (inconsistent everywhere) or sed (sometimes too slow). But from personal experience, whenever re-reading these expr-isms, I have to go back to the man page. So, I would just comment that every usage of expr be commented...
There was a time when all you had was the original Bourne shell. It lacked some commonly required features, so tools like expr and test were implemented to perform them. In this day and age, there are usually better tools, many of them built into any modern shell. I guess test is still hanging in there, but nobody seems to be missing expr.
Upvoting since I needed something that worked in Bourne shell, and everything else appears to be bash-specific.
expr: syntax error: unexpected argument ‘.*.*’ bash: [: -ne: unary operator expected
P
Peter Mortensen

Since the POSIX/BusyBox question is closed without providing the right answer (IMHO), I'll post an answer here.

The shortest possible answer is:

[ ${_string_##*$_substring_*} ] || echo Substring found!

or

[ "${_string_##*$_substring_*}" ] || echo 'Substring found!'

Note that the double hash is obligatory with some shells (ash). Above will evaluate [ stringvalue ] when the substring is not found. It returns no error. When the substring is found the result is empty and it evaluates [ ]. This will throw error code 1 since the string is completely substituted (due to *).

The shortest more common syntax:

[ -z "${_string_##*$_substring_*}" ] && echo 'Substring found!'

or

[ -n "${_string_##*$_substring_*}" ] || echo 'Substring found!'

Another one:

[ "${_string_##$_substring_}" != "$_string_" ] && echo 'Substring found!'

or

[ "${_string_##$_substring_}" = "$_string_" ] || echo 'Substring found!'

Note the single equal sign!


P
Peter Mortensen

My .bash_profile file and how I used grep:

If the PATH environment variable includes my two bin directories, don't append them,

# .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

Is this an answer?
upvote. why bother to learn how Bash does it when grep, far more powerful, is more than likely going to be available. also extend it a bit further by matching against a list of patterns: grep -q -E 'pattern1|...|patternN'.
P
Peter Mortensen

Extension of the question answered here How do you tell if a string contains another string in POSIX sh?:

This solution works with special characters:

# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
    string="$1"
    substring="$2"

    if echo "$string" | $(type -p ggrep grep | head -1) -F -- "$substring" >/dev/null; then
        return 0    # $substring is in $string
    else
        return 1    # $substring is not in $string
    fi
}

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*"

The test contains "-n" "n" doesn't work here, because echo -n will swallow the -n as an option! A popular fix for that is to use printf "%s\n" "$string" instead.
n
nyuszika7h

grep -q is useful for this purpose.

The same using awk:

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

Output:

Not Found

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

Output:

Found

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


echo is unportable, you should be using printf '%s' "$string" instead. I'm editing the answer because the user doesn't appear to exist anymore.
In what way is echo not portable, @nyuszika7h?
r
ride

I like sed.

substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1

Edit, Logic:

Use sed to remove instance of substring from string

If new string differs from old string, substring exists


Please add some explanation. Imparting the underlying logic is more important than just giving the code, because it helps the OP and other readers fix this and similar issues themselves
P
Peter Mortensen

I found to need this functionality quite frequently, so I'm using a home-made shell function in my .bashrc like this which allows me to reuse it as often as I need to, with an easy to remember name:

function stringinstring()
{
    case "$2" in
       *"$1"*)
          return 0
       ;;
    esac
    return 1
}

To test if $string1 (say, abc) is contained in $string2 (say, 123abcABC) I just need to run stringinstring "$string1" "$string2" and check for the return value, for example

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO

[[ "$str" == $substr ]] && echo YES || echo NO
I'm pretty sure the x hack is only required for very old shells.
The proper -- and immediately recognizable -- name for your function would be strstr() :-)
@MikhailT.: feel free to handle this as you like... :-)
P
Pipo

The generic needle haystack example is following with variables

#!/bin/bash

needle="a_needle"
haystack="a_needle another_needle a_third_needle"
if [[ $haystack == *"$needle"* ]]; then
    echo "needle found"
else
    echo "needle NOT found"
fi

K
Koichi Nakashima
case $string in (*foo*)
  # Do stuff
esac

This is the same answer as https://stackoverflow.com/a/229585/11267590. But simple style and also POSIX Compliant.


E
Eduardo Cuomo

Exact word match:

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

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

P
Peter Mortensen

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 is available at Sourceforge.net.


E
Ethan Post

I use this function (one dependency not included but obvious). It passes the tests shown below. If the function returns a value > 0 then the string was found. You could just as easily return 1 or 0 instead.

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
}

The suspense! What is the dependency?
The "str_escape_special_characters" function. It is in GitHub arcshell_str.sh file. arcshell.io will get you there.
str_escape_special_characters appears to have become str_escape. see arcshell_str.sh @ arclogicsoftware/arcshell
f
franzisk

You can use a logic && to be more compact

#!/bin/bash

# NO MATCH EXAMPLE
string="test"
[[ "$string" == *"foo"* ]] && {
        echo "YES"
}

# MATCH EXAMPLE
string="tefoost"
[[ "$string" == *"foo"* ]] && {
        echo "YES"
}

B
BobMonk
msg="message"

function check {
    echo $msg | egrep [abc] 1> /dev/null

    if [ $? -ne 1 ];
    then 
        echo "found" 
    else 
        echo "not found" 
    fi
}

check

This will find any occurance of a or b or c


J
JanB

With jq:

string='My long string'
echo $string | jq -Rr 'select(contains("long"))|"It is there"'

The hardest thing in jq is to print the single quote:

echo $string | jq --arg quote "'" -Rr 'select(contains("long"))|"It\($quote)s there"'

Using jq just to check the condition:

if jq -Re 'select(contains("long"))|halt' <<< $string; then
    echo "It's there!"
fi