-1

I am trying to pass a regular expression as a parameter. What should I fix in my code? My goal is to send find and the regular expression string, then use grep on the parameter so I can do whatever I want with what grep finds (which is print the count of occurrences).

This is what I send:

$ ./lab12.sh find [Gg]reen

Here's my bash code:

if [[ "$1" == "find" ]]
then
    declare -i cnt=0
    for file in /tmp/beatles/*.txt ; do
        if [[ grep -e $2 ]]  //problem is here...
        then
            ((cnt=cnt+1))
        fi
    done
    echo "$cnt songs contain the pattern "$2""
fi        
wjandrea
  • 28,235
  • 9
  • 60
  • 81
N.N Beats
  • 23
  • 5
  • 1
    Square brackets are part of glob syntax (wildcards) – wjandrea Jan 17 '22 at 14:59
  • 1
    It would produce undesirable results (pathname expansion would happen) if you have any files starting with `G` or `g` in your current directory. If not it would go unmodified as `[Gg]reen`. To produce desirable results, single quote the whole string – Inian Jan 17 '22 at 15:06
  • Also, unmatched patterns being treated literally is only the *default* behavior of `bash`. You can configure it to raise an error (`shopt -s failglob`) or disappear (`shopt -s nullglob`) as well. – chepner Jan 17 '22 at 15:21
  • 1
    Take a look at https://www.shellcheck.net/. It is a shell script validator and will also find practices that may cause your problems. See also https://wizardzines.com/comics/shellcheck/ – Andy Lester Jan 17 '22 at 15:55

1 Answers1

2

The if statement takes a command. [[ being one, and grep is another, writing [[ grep ... ]] is essentially as wrong as writing vim grep, or cat grep etc, just use:

if grep -q -e "$pattern"
then
  ... 

instead.

The -q switch to grep will disable output, but set the exit status to 0 (success) when the pattern is matches, and 1 (failure) otherwise, and the if statement will only execute the then block if the command succeded.

Using -q will allow grep to exit as soon as the first line is matches.

And as always, remember to wrap your paremeter expansions in double quotes, to avoid pathname expansion and wordsplitting.

Note that square brackets [...] will be interpreted by your calling shell, and you should escape them, or wrap the whole pattern in quotes.

It's always recommended use single quotes, as the only special character is another single quote.

$ ./lab12.sh find '[Gg]reen'
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • Not just "can"; it *will* be interpreted. The question is whether the pattern produces any matches. – chepner Jan 17 '22 at 15:23
  • @chepner I guess it depends on what shell calls the program, and how it's configured. For all practical matter you are correct. – Andreas Louv Jan 17 '22 at 15:25