0

I want to detect if the input argument contains some sub-string.

I tried below scripts:

#1:

#!/bin/sh

if [ $1 = abc ] then echo contains abc else echo not contains abc fi

#2:

if  [ "$1" = "*abc*" ]
then
    echo contains abc
else
    echo not contains abc
fi

#3:

if  [ "$1" = *"abc"* ]
then
    echo contains abc
else
    echo not contains abc
fi

All #1 ~ #3 don't work.

But below ones with [[ can easily work:

#4:

if  [[ $1 = *"abc"* ]]
then
    echo contains abc
else
    echo not contains abc
fi

#5:

if  [[ $1 = *abc* ]]
then
    echo contains abc
else
    echo not contains abc
fi

So is it possible to make the single [ work?

ADD 1 - 10:55 AM 9/21/2021

Just found a VERY USEFUL thread:

What is the difference between the Bash operators [[ vs [ vs ( vs ((?

smwikipedia
  • 1,203
  • So, you tagged this with [[tag:bash]], and ask if it's possible to make the single [ work with the pattern. Counter-question: is there a reason to want to use [ in particular, when Bash supports [[ which does exactly what you want? – ilkkachu Sep 21 '21 at 07:35

2 Answers2

0

[[ is a shell builtin. It is a more versatile version of [, which is an executable in /usr/bin (see the documentation and man page of test for further details).

[ is more portable, while [[ is more versatile, and it's generally the variant you should use.

if  [[ $1 == *"abc"* ]]; then
    echo "substring present"
else
    echo "substring not present"
fi

Another good way of testing for substring is to use the regex operator:

if [[ "$1" =~ .*"abc".* ]]; then
    echo "contains"
else
    echo "doesn't contain"
fi

Note that the expression after =~ is a regular expression and not just globbing.


Yet another way of checking substrings is to use case:

case $1 in
    *"abs"*)
        echo "substring present"
        ;;
    *)
        echo "substring not present"
        ;;
esac

Alternatively, you can use grep, as CPH explained in his post. However you need to make sure to use a here-doc:

if grep -q "abc" <<< "$STR"; then
    echo "substring present"
else
    echo "substring not present"
fi
polemon
  • 11,431
  • 1
    I remember [[ is a keyword, which is syntax concept, while a builtin is some built-in command. Correct me if I am wrong because I am new to bash. – smwikipedia Sep 21 '21 at 02:20
  • @smwikipedia it is a command, invoking test just like [, except it's part of bash. Run man test to get a man page for the "normal" [. – polemon Sep 21 '21 at 02:22
  • I just tried type [[. It gives me [[ is a shell keyword. And I tried type [. It gives me [ is a shell builtin. I tried in CygWin. – smwikipedia Sep 21 '21 at 02:24
  • @smwikipedia you can also do help [[ to get a quick synopsis from within bash. – polemon Sep 21 '21 at 02:25
  • 1
    @smwikipedia that's because the modern bash abstracts a bunch of "standard" POSIX commands like true, false, and a bunch others, like [. Technically there's little difference, as it doesn't work like an operator. Operators for instance are things like '&' to run something in the background, or < and > and | to re-route STDOUT and STDIN (and STDERR). – polemon Sep 21 '21 at 02:30
-2

Is there a reason you want to use single brackets?

A simpler way would be something like this:

if echo "$1" | grep 'abc' > /dev/null; then
    # Do if true substring found
else
    # substring not found
fi

If you're not familiar with the grep command, it just searches a string for the parameter/value you give. You can ignore case if you want using the -i flag, the above will look specifically for a lowercase 'abc' in your parameter '$1'

Philippos
  • 13,453
CPH
  • 105
  • 2
  • Just curious. It seems [[ is an enhancement comes after [. Just wonder how people do that before [[. – smwikipedia Sep 21 '21 at 02:18
  • 1
    Ahh I see. I'll give my understanding here: [[ ]] are used for operators (greater than, less than, etc). [ ] is used for string comparisons. I just noticed this though, what you have in your question may work (not 100% sure though). You just need to change = to == (I believe) – CPH Sep 21 '21 at 02:42
  • The only hesitation I have on it working is the wildcard *. I don't know if that will be accepted as proper syntax – CPH Sep 21 '21 at 02:44
  • I tried if [ "$1" == *abc* ], still doesn' work. I will try some more. – smwikipedia Sep 21 '21 at 02:45
  • the only thing that MAY work would be *"abc"*, but even then I doubt it. doing *abc* will not compile, and will probably give an error similar to "abc is not a command" or something along those lines. – CPH Sep 21 '21 at 02:47