Um alias é interno ao shell em que está definido. Não é visível para outros processos. O mesmo vale para funções de shell. xargs
é um aplicativo separado, que não é um shell, portanto não possui um conceito de alias ou funções.
Você pode fazer xargs chamar um shell em vez de chamar grep
diretamente. No entanto, apenas invocar um shell não é suficiente, você precisa definir o alias nesse shell também. Se o alias estiver definido no seu .bashrc
, você pode obter esse arquivo; no entanto, isso pode não funcionar, você .bashrc
realiza outras tarefas que não fazem sentido em um shell não interativo.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E regex_here "$@"' _
Cuidado com os meandros da cotação aninhada ao digitar a regexp. Você pode simplificar sua vida passando o regexp como um parâmetro para o shell.
find . -name '*.py' | xargs bash -c '. ~/.bashrc; grep -E "$0" "$@"' regex_here
Você pode executar a pesquisa de alias explicitamente. Então xargs
vai ver grep -n --color=always
.
find . -name '*.py' | xargs "${BASH_ALIASES[grep]}" regex_here
No zsh:
find . -name '*.py' | xargs $aliases[grep] regex_here
A propósito, observe que find … | xargs …
quebras nos nomes de arquivos que contêm espaços (entre outros) . Você pode corrigir isso alterando para registros delimitados por nulo:
find . -name '*.py' -print0 | xargs -0 "${BASH_ALIASES[grep]}" regex_here
ou usando -exec
:
find . -name '*.py' -exec "${BASH_ALIASES[grep]}" regex_here {} +
Em vez de ligar find
, você pode fazer tudo inteiramente dentro do shell. O padrão glob **/
percorre diretórios recursivamente. No bash, você precisa executar shopt -s globstar
para ativar esse padrão glob primeiro.
grep regex_here **/*.py
Isso tem algumas limitações:
- Se muitos arquivos corresponderem (ou se tiverem caminhos longos), o comando poderá falhar porque excede o comprimento máximo da linha de comando.
- No bash ≤4.2 (mas não nas versões mais recentes, nem no ksh ou no zsh), ocorre novamente
**/
em links simbólicos para diretórios.
Outra abordagem é usar a substituição de processos, conforme sugerido por MariusMatutiae .
grep regex_here <(find . -name '*.py')
Isso é útil quando **/
não é aplicável: para find
expressões complexas ou no bash ≤4.2 quando você não deseja se recuperar sob links simbólicos. Observe que isso quebra nos nomes de arquivos que contêm espaços; uma solução alternativa é definir IFS
e desativar o globbing , mas está começando a ficar um pouco complexo:
(IFS=$'\n'; set -f; grep regex_here <(find . -name '*.py') )