Comandos repetidos em um pipeline de bash

4

Às vezes, os comandos se repetem no comando de pipeline. Por exemplo (apenas para ilustrar):

$ grep -lF 'pattern' ./foo/**/*.bar | xargs dirname | xargs dirname

Existe uma maneira de encurtar o comando de encadeamento? Por exemplo, eu tenho um comando:

$ ... | some-command | some-command | some-command | ...

Gostaria de obter o mesmo resultado com algo parecido com o seguinte

$ ... | (some-command) ^ 3 | ...

Claro, isso não funcionaria, mas ilustra o que eu gostaria de fazer.

    
por Loom 04.02.2014 / 17:21

2 respostas

3

Recursão + mal:

repiper() { 
    local -i n="$1";
    shift;
    if (( n )); then
        eval "$@" | repiper $((n-1)) "$@";
    else
        eval "$@";
    fi
}

$ grep -lRF function dev/jquery/build | repiper 3 xargs -n1 dirname | head
.
.
dev
dev
dev
dev
$ grep -lRF function dev/jquery/build | repiper 1 xargs -n1 dirname | head
dev/jquery
dev/jquery
dev/jquery/build
dev/jquery/build
dev/jquery/build
dev/jquery/build
$ grep -lRF function dev/jquery/build | repiper 0 xargs -n1 dirname | head
dev/jquery/build
dev/jquery/build
dev/jquery/build/tasks
dev/jquery/build/tasks
dev/jquery/build/tasks
dev/jquery/build/tasks
    
por 05.02.2014 / 04:51
0

Não é bonito, mas acredito que você pode fazer o que quiser usando um tempo e um loop.

$ seq 5 | while read -r f; do for i in {1..3}; do echo "[$i]: blah $f";done; done
[1]: blah 1
[2]: blah 1
[3]: blah 1
[1]: blah 2
[2]: blah 2
[3]: blah 2
[1]: blah 3
[2]: blah 3
[3]: blah 3
[1]: blah 4
[2]: blah 4
[3]: blah 4
[1]: blah 5
[2]: blah 5
[3]: blah 5

Aqui está o constructo dividido:

$ <CMD> | while read -r f; do 
    for i in <range>; do 
        ...do command some num. of times...
    done 
done

Outras abordagens

  1. A outra maneira de visualizar isso seria criar uma função de shell ( function () {...} ) e chamar isso em vez de xargs ... várias vezes. Esta função pode pegar 2 argumentos, um número de vezes para rodar o argumento e um argumento para rodar.

  2. Você também pode criar um script de shell que contenha um loop for que você possa passar para 2 argumentos. O número de vezes para executar o X e o argumento para operar no X.

por 04.02.2014 / 17:55