No meu .bash_aliases eu defini uma função que eu uso da linha de comando assim:
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
A função constrói um comando grep que canaliza o resultado para outro comando grep (infelizmente confuso porque estou preso em uma versão antiga):
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
}
Eu defini outra função que chama essa função:
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[@]}"
}
Na linha de comando, eu chamo essa função assim:
search-some-set-of-files SomeTextIWantToSearchFor
Por algum motivo, os resultados incluem todos os arquivos nos diretórios de destino. Ou seja, os resultados não são filtrados pelo grep de acordo com os nomes de arquivo que eu especifiquei.
Se eu alterar a última linha da função search-some-set-of-files
para ecoar o comando, obtenho isto:
$ search-some-set-of-files SomeTextIWantToSearchFor
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
Qual é exatamente o que eu quero. Se eu copiar esse comando (ou digitá-lo na íntegra) na linha de comando, os resultados são como deveriam ser.
Se eu ativar o modo de depuração ( set -x
), posso ver que cada argumento está sendo citado separadamente pelo 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...
Então eu acho que o problema está em como os argumentos estão sendo passados para a função search
. Como faço para corrigir isso?