Eu tento colocar find
dentro da função e pegar um argumento passado para esta função com o seguinte exemplo de trabalho mínimo:
função DO { ls $(find. -type f -name "$@" -exec grep -IHl "TODO" {} \;) }
Mas, quando executo DO *.tex
, recebo “find: os caminhos devem preceder a expressão:”. Mas quando eu faço diretamente:
ls $(find . -type f -name "*.tex" -exec grep -IHl "TODO" {} \;)
então recebo todos os arquivos TeX que contêm "TODO".
Eu tento muitas coisas na DO
função, como \"$@\"
, '$@'
, mudo as aspas, mas o comportamento continua o mesmo.
Então, o que fazer para forçar a encontrar o trabalho dentro da função?
Existem alguns problemas no seu código:
O
*.tex
padrão será expandido ao chamar a funçãoDO
, se corresponder a qualquer nome de arquivo no diretório atual. Você terá que citar o padrão como'*.tex'
,"*.tex"
ou\*.tex
ao chamar a função.O
ls
não é necessário. Você já tem os doisfind
egrep
pode relatar os nomes de caminho dos arquivos encontrados.-name "$@"
só funciona corretamente se"$@"
contiver um único item. Seria melhor usar-name "$1"
. Para uma solução que permite vários padrões, veja abaixo.A função pode ser escrita
Chamando esta função como
vai fazê-lo executar
Isso geraria uma lista de nomes de caminho de arquivos com esses sufixos de nome de arquivo, se os arquivos contivessem a string
TODO
.Para usar
grep
em vez defind
imprimir os nomes de caminho encontrados, altere o-exec ... -print
bit para-exec grep -lF 'TODO' {} +
. Isso será mais eficiente, especialmente se você tiver um grande número de nomes de arquivos correspondentes à(s) expressão(ões) fornecida(s). Em ambos os casos, você definitivamente não precisa usarls
.Para permitir que o usuário use
sua função pode ser alterada para
Você precisa citar o parâmetro para a função, caso contrário, o shell o expande e a função obtém uma lista de arquivos, não uma máscara curinga:
Você pode usar apenas
"$1"
em vez de"$@"
, pois haverá apenas um parâmetro.