Quando você executa findinfiles {*.js,*.html,} {release,dev,} "span"
, eis o que acontece:
- O Bash analisa aspas e divide o comando em palavras:
findinfiles
,{*.js,*.html,}
{release,dev,}
span
. - O Bash expande as chaves, resultando na lista de palavras
findinfiles
,*.js
,*.html
,release
,dev
,span
. - O Bash expande os padrões curinga
*.js
e*.html
para a lista de nomes de arquivos correspondentes. Se nenhum nome de arquivo corresponder a um padrão, ele será deixado sozinho. - Bash consulta o nome
findinfiles
, descobre que é uma função e executa a função com os parâmetros fornecidos.
Você pode impedir que as chaves e curingas sejam expandidos na chamada de função, mas as chaves aparecerão literalmente nos argumentos, o que não é particularmente útil.
Sugiro alterar o formato da sua chamada de função. Em vez de usar chaves, use apenas vírgulas e divida manualmente os argumentos em vírgulas dentro da função.
findinfiles () {
local patterns="$1" excludes="$2" pattern="$3"
shift 3
typeset -a cmd dirs
if [[ $# -eq 0 ]]; then dirs=(.); else dirs=("$@"); fi
cmd=(grep --color=auto -iRnHr)
local IFS=,
for x in $patterns; do
cmd+=("--include=$x")
done
for x in $excludes; do
cmd+=("--exclude-dir=$x")
done
"${cmd[@]}" "${dirs}"
}
Explicações:
- Armazene os três primeiros parâmetros em variáveis locais. Quaisquer parâmetros extras são diretórios para pesquisar.
- Defina
dirs
como a lista de parâmetros extras. Se não houver nenhum, use.
(diretório atual). -
Defina
IFS
como vírgula. Quando um script contém uma expansão de variável sem nome como$patterns
e$excludes
acima, o shell executa o seguinte:- Substitua a variável pelo seu valor.
- Divida a variável em palavras separadas, sempre que contiver um caractere que esteja presente em
IFS
. Por padrão,IFS
contém caracteres de espaço em branco (espaço, tabulação e nova linha). - Trate cada palavra como um padrão curinga e expanda-a para a lista de arquivos correspondentes. Se não houver nenhum arquivo correspondente, deixe o padrão sozinho.
(Para evitar essas etapas de expansão, use aspas duplas em torno da substituição de variável, como em
patterns="$1"
e assim por diante no script acima.) -
A função cria a linha de comando para executar incrementalmente na variável de matriz
cmd
. No final, o comando é executado.
Como alternativa, você pode criar as seguintes configurações:
shopt -s extglob globstar
fif_excludes='release dev'
alias fif='grep --color=auto -inH $fif_excludes'
Executar comandos como
fif span **/*.@(js|html)
Explicações:
-
shopt -s extglob
ativa o formato@(js|html)
do padrão de caractere curinga, que corresponde ajs
ouhtml
. (Esta opção ativa outros formulários padrão, veja o manual para detalhes). -
shopt -s globstar
ativa o padrão**/
que corresponde a subdiretórios em qualquer profundidade (isto é, realiza uma travessia recursiva). - Para alterar a lista de exclusões (que espero que não aconteça com frequência), modifique a variável
fif_excludes
.