
Estou querendo criar um built-in personalizado bash
- como time
por exemplo. Isso é possível? Se não for, é possível em outro shell?
Por exemplo, eu quero fazer isso: map find -name '*.js' | xargs grep func1
e executá-lo find -name '*.js' | xargs grep func1
dentro de cada diretório do CWD. Observe que tudoincluindo o tuboé passado para map
.
O objetivo é aplicar um comando em vários diretórios. Eu escrevi um script chamado map
que eval
abrange $1
tudo o ls
que produz. No entanto, se o comando que desejo executar incluir canais, redirecionamentos, etc., terei que citar tudo dentro de uma string. Estou procurando uma maneira de não ter que fazer isso.
Além disso, estou curioso para saber se isso é possível;)
Responder1
ATT ksh, bash e zsh possuem, cada um, um sistema de carregamento de módulo dinâmico que permite carregar código adicional em uma instância de shell existente, e o código carregado dinamicamente pode implementar novos componentes integrados. O que você está perguntando requer mais do que um novo built-in: requer uma nova sintaxe, e acho que nenhum dos shells pode lidar com isso. Você teria que modificar o analisador no código-fonte do shell.
No zsh, você pode chegar perto da sintaxe desejada:
for x (*/) (cd $x && pipeline)
Você pode criar um alias alias map='for x (*/) (cd $x &&'
, mas ainda precisará do parêntese de fechamento no final. Você pode obter exatamente a sintaxe desejada com um hack grosseiro:
alias map='map__PWD=$PWD; for x (./*/ "") cd $map__PWD${x#.}/ && [[ -z $x ]] || '
Isto é tão feio, frágil e não generalizável que não vou explicar. Não pense em usá-lo se não entender completamente como funciona.
Responder2
Neste caso, algo como
find . -type f -name "*.js" -exec grep -qF "func1" {} \; -print
provavelmente seria suficiente encontrar os nomes dos *.js
arquivos em qualquer lugar dentro ou abaixo do diretório atual que contém a string func1
.
Se você quiser evitar os arquivos que estão no diretório atual:
find . -mindepth 2 -type f -name "*.js" -exec grep -qF "func1" {} \; -print
Com -mindepth 2
, find
não corresponderá a nada na "profundidade 1", ou seja, no diretório atual.
Esta última coisa basicamente faz o que você pede. Ele é executado efetivamente grep
em cada subdiretório do diretório atual.