bash integrado personalizado

bash integrado personalizado

Estou querendo criar um built-in personalizado bash- como timepor 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 func1e executá-lo find -name '*.js' | xargs grep func1dentro 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 mapque evalabrange $1tudo o lsque 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 *.jsarquivos 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, findnã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 grepem cada subdiretório do diretório atual.

informação relacionada