In my .bash_aliases I have defined a function that I use from the command line like this:
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
The function builds a grep command that pipes the result to another grep command (unfortunately convoluted because I am stuck on an old version):
search() {
local file_names opt OPTARG OPTIND pattern
file_names=()
while getopts ":n:" opt; do
case $opt in
n)
file_names+=( "$OPTARG" )
;;
esac
done
shift $((OPTIND-1))
pattern="$1"
shift
if (( ${#file_names[@]} > 0 )); then
file_names="${file_names[@]}"
file_names=${file_names// /':\|'}:
grep -I -r "$pattern" "$@" | grep "$file_names"
else
grep -I -r "$pattern" "$@"
fi
}
I have defined another function that calls this function:
search-some-set-of-files() {
local file_names directories
file_names=( "-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml" )
directories=( "/c/code/website/" "/c/stuff/something/whatever/" )
search "${file_names[@]}" "$@" "${directories[@]}"
}
From the command line, I call this function like this:
search-some-set-of-files SomeTextIWantToSearchFor
For some reason, the results include every single file in the target directories. i.e., the results are not filtered by grep according to the file names I specified.
If I change the last line of the search-some-set-of-files
function to echo the command, I get this:
$ search-some-set-of-files SomeTextIWantToSearchFor
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
Which is exactly what I want. If I copy that command (or type it verbatim) into the command line, the results are as they should be.
If I enable debugging mode (set -x
), I can see that each argument is being quoted separately by the shell:
$ search-some-set-of-files SomeTextIWantToSearchFor
+ search-some-set-of-files SomeTextIWantToSearchFor
+ local file_names directories
+ file_names=("-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml")
+ directories=("/c/code/website/" "/c/stuff/something/whatever/")
+ search '-n page1.cshtml' '-n page2.cshtml' '-n page3.cshtml' SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
+ return
+ etc...
So I think the problem lies in how the arguments are being passed to the search
function. How do I fix this?