Eu tenho um programa UNIX de caixa preta usado em um shell Bash que lê colunas de dados de stdin, os processa (aplicando um efeito de suavização) e depois envia para stdout. Eu uso por pipes UNIX, como
generate | smooth | plot
Para mais suavização, posso repetir a suavização, para que seja invocada na linha de comando do Bash como
generate | smooth | smooth | plot
ou mesmo
generate | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | plot
Isso está ficando desagradável. Eu gostaria de fazer um wrapper Bash para poder canalizar smooth
e alimentar sua saída de volta em uma nova instância de smooth
um número arbitrário de vezes, algo como
generate | newsmooth 5 | plot
ao invés de
generate | smooth | smooth | smooth | smooth | smooth | plot
Minha primeira tentativa foi um script Bash que gerou arquivos temporários no diretório atual e os excluiu, mas ficou feio quando eu não estava em um diretório com acesso de gravação e também deixou arquivos de lixo quando interrompido.
Não há argumentos para o smooth
programa.
Existe uma maneira mais elegante de "empacotar" esse programa para parametrizar o número de chamadas?
Você poderia envolvê-lo em uma função recursiva:
Você usaria isso como
que seria equivalente a
Se você puder digitar tantas vírgulas quanto a quantidade de
smooth
comandos que desejar, poderá aproveitar a expansão de chaves separada por vírgulas do shell.TL; RD
A linha de comando inteira para seu caso de exemplo seria:
Observação:
smooth |
|
antesplot
porque isso está incluído na últimasmooth |
string produzida pela expansão Bracesmooth
, contanto que você possa incluí-los corretamente na parte fixa entre aspas que precede a chave aberta; em qualquer caso, lembre-se de que você os forneceria a todas as repetições do comandoComo funciona
A Expansão de Brace separada por vírgula permite que você produza dinamicamente strings, cada uma feita de uma parte fixa especificada mais as partes variáveis especificadas. Produz tantas strings quantas as partes variáveis indicadas, como
a{b,c,d}
produzab ac ad
.O pequeno truque aqui é que se você preferir fazer uma lista de partes variáveis vazias , ou seja, apenas com vírgulas dentro dos colchetes, a Expansão Brace produzirá apenas cópias apenas da parte fixa. Por exemplo:
vai produzir:
Observe que 4 vírgulas produzem 5
smooth
strings. É exatamente assim que esta Expansão Brace funciona: ela produz strings com quantas vírgulas mais uma.É claro que no seu caso você também precisa de um
|
separating eachsmooth
, então apenas adicione-o na parte fixa, mas tome cuidado para citá-lo corretamente para que o shell não o interprete de uma só vez. Aquilo é:vai produzir:
Tenha o cuidado de colocar sempre a parte fixa imediatamente adjacente à escora aberta, ou seja, sem espaços entre o
'
e o{
.(Observe também que para formar a parte fixa você também pode usar aspas duplas em vez de aspas simples, se precisar expandir as variáveis do shell na parte fixa. Apenas tome cuidado com o escape extra que é necessário quando alguns caracteres especiais do shell ocorrem dentro de uma string com aspas duplas).
Neste ponto, você precisa de um
eval
aplicado a essa string para fazer com que o shell finalmente a interprete como o comando em pipeline que deveria ser.Assim, para resumir tudo, toda a linha de comando para o seu caso de exemplo seria: