Using variable to skip grep template in bash

I am struggling with passing multiple 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:

  • define / determine where grep
  • assign a variable (GREP_MY_OPTIONS) containing the parameters, I will go to grep
  • assign multiple templates GREP_MY_OPTIONS
  • using grep and templates that I saved in $ GREP_MY_OPTIONS, search for multiple files in a path that contains spaces, and hold them in an array

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

/ bin / grep: invalid option -

What am I doing wrong? If there are no spaces in the path, everything works fine, so I think it has something to do with IFS, but I'm not sure.

+4
source share
3 answers

If you create GREP_MY_OPTIONS as an array instead of a simple string, you can get the original script outline for reasonable use:

 #!/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 don’t understand why you are using GREP="$(which grep)" , since you will execute the same grep as if you wrote grep directly - if, I suppose, you have an alias for grep (which then is the problem, not the alias grep ).

+1
source

If you want to grep some content in a set of paths, you can do the following:

 find <directory> -type f -print0 | grep "/home/user/this path has spaces in it/\"*\"/abc.xyz" | xargs -I {} grep <your_options> -f <patterns> {} 

So, <patterns> is a file containing the patterns you want to search in each file from the directory .

Given your answer, this will do what you want:

 find "/path\ with\ spaces/" -type f | xargs -I {} grep -H -c -e 2013-01-17 {} 

From man grep :

  -H, --with-filename Print the file name for each match. This is the default when there is more than one file to search. 

Since you want to insert elements into an array, you can do the following:

 IFS=$'\n'; array=( $(find "/path\ with\ spaces/" -type f -print0 | xargs -I {} grep -H -c -e 2013-01-17 "{}") ) 

And then use the values ​​like:

 echo ${array[0]} echo ${array[1]} echo ${array[...]} 

When using variables to pass parameters, use eval to evaluate the entire string. Follow these steps:

 parameters="-H -c" eval "grep ${parameters} file" 
+3
source

You can do one thing without making things complicated:

First make the change directory in the script as follows:

 cd /home/user/this\ path\ has\ spaces\ in\ it/ $ pwd /home/user/this path has spaces in it 

or

 $ cd "/home/user/this path has spaces in it/" $ pwd /home/user/this path has spaces in it 

Then do whatever you want in the script.

 $(${GREP} ${GREP_MY_OPTIONS} */abc.xyz) 

EDIT :

 [ sgeorge@sgeorge-ld stack1]$ ls -l total 4 drwxr-xr-x 2 sgeorge eng 4096 Jan 19 06:05 test tesd [ sgeorge@sgeorge-ld stack1]$ cat test\ tesd/file SUKU [ sgeorge@sgeorge-ld stack1]$ grep SUKU */file SUKU 

EDIT :

 [ sgeorge@sgeorge-ld stack1]$ find */* -print | xargs -I {} grep SUKU {} SUKU 
0
source

All Articles