Search code examples
arraysbashdesign-patternsgrepifs

Using a variable to pass grep pattern in bash


I am struggling with passing several grep patterns that are contained within a variable. This is the code I have:

#!/bin/bash
GREP="$(which grep)"
GREP_MY_OPTIONS="-c"
for i in {-2..2}
do
  GREP_MY_OPTIONS+=" -e "$(date --date="$i day" +'%Y-%m-%d')
done
echo $GREP_MY_OPTIONS

IFS=$'\n'
MYARRAY=( $(${GREP} ${GREP_MY_OPTIONS} "/home/user/this path has spaces in it/"*"/abc.xyz" | ${GREP} -v :0$ ) )

This is what I wanted it to do:

  • determine/define where grep is
  • assign a variable (GREP_MY_OPTIONS) holding parameters I will pass to grep
  • assign several patterns to GREP_MY_OPTIONS
  • using grep and the patterns I have stored in $GREP_MY_OPTIONS search several files within a path that contains spaces and hold them in an array

When I use "echo $GREP_MY_OPTIONS" it is generating what I expected but when I run the script it fails with an error of:

/bin/grep: invalid option -- ' '

What am I doing wrong? If the path does not have spaces in it everything seems to work fine so I think it is something to do with the IFS but I'm not sure.


Solution

  • If you build the GREP_MY_OPTIONS as an array instead of as a simple string, you can get the original outline script to work sensibly:

    #!/bin/bash
    path="/home/user/this path has spaces in it"
    GREP="$(which grep)"
    GREP_MY_OPTIONS=("-c")
    j=1
    for i in {-2..2}
    do
        GREP_MY_OPTIONS[$((j++))]="-e"
        GREP_MY_OPTIONS[$((j++))]=$(date --date="$i day" +'%Y-%m-%d')
    done
    
    IFS=$'\n'
    MYARRAY=( $(${GREP} "${GREP_MY_OPTIONS[@]}" "$path/"*"/abc.xyz" | ${GREP} -v :0$ ) )
    

    I'm not clear why you use GREP="$(which grep)" since you will execute the same grep as if you wrote grep directly — unless, I suppose, you have some alias for grep (which is then the problem; don't alias grep).