5

Sometimes commands repeat in pipeline command. For example (just to illustrate):

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

Is there a way to shorten chaining command? For example, I have a command:

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

I'd like to get same result with something like to the following

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

Of course, it wouldn't work, but it illustrates what I'd like to make.

2
  • 2
    There is no way to do that Commented Feb 4, 2014 at 16:54
  • @AlexLayton I beg to differ. Commented Feb 5, 2014 at 3:53

2 Answers 2

3

Recursion + evil:

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
0
0

Not beautiful but I believe you can do what you want using a while and a for 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

Here's the construct broken out:

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

Other approaches

  1. The other way to view this would be to create a shell function (function () {...}) and call that instead of xargs ... multiple times. This function coud take 2 arguments, a number of times to run argument, and an argument to run.

  2. You could also create a shell script that would contain a for loop that you could pass into it 2 arguments. The number of times to run X, and the argument to operate on X.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.