This seems like a great time to subscribe my RSS !

Last day, I needed to repeat a shell command a arbitrary number of times, and all I found was the suggestion to use the repeat command.

Sadly, I haven’t been able to found that command in Ubuntu, but after some research I could luckily find something useful. What follows is a very simple bash implementation of the repeat command.

First, open your .bash_aliases file:

xdg-open ~/.bash-aliases

Second, paste these lines at the bottom of the file and save:

repeat() {
    n=$1
    shift
    while [ $(( n -= 1 )) -ge 0 ]
    do
        "$@"
    done
}

Third, either close and open again your terminal, or type:

source ~/.bash_aliases

Et voilà ! You can now use it like this:

repeat 5 echo Hello World !!!

or

repeat 5 ./myscript.sh

Hope this can help you !

5 Responses

  1. Evan M

    for i in seq 5; do echo Hello; done

  2. > for i in seq 5; do echo Hello; done

    or:

    for i in {1..5}; do echo Hello World \!\!\! ; done

    ;-)

    Also the “repeat” command is a built-in of Csh-type shells, so in Ubuntu you could apt-get install csh or tcsh in order to use it. But then it won’t be bash anymore.. :-)

    Cheers,
    Christophe.

    = I keep trying to tell my boss that no, Satan is a tool of Linux, not the other way around. –Anonymous =

  3. Alexander Reece

    xargs has proven a valuable tool. Whenever I need to loop over something, xargs often does the job.

    It may seem a bit verbose, (having to pass two parameters to xargs). Overall its pretty short an easy to read.

    seq 1 10 | xargs -I{} -n1 echo ‘Hello World!’

    Those two parameters are the most commonly used parameters for me, as such, I have aliases for them in my .bashrc (listed below). Running over something x times becomes as simple as:

    $ seq 1 10 | xx1 echo “Hello World”

    Want to include a number in your command? Use {} (you may change this in the xargs arguments)
    $ seq 1 10 | xx1 echo “Hello World #{}”

    This not only has the advantage of repeating commands, but you can repeat commands for a variety of loops. (Repeat this once for each directory). I often chain them together:

    # run a command twenty times for each file located beneath the current directory
    $ find -type f -print0 | xx10 seq 1 20 | xx0 echo “Greetings World”

    If you want to get real fancy– multitask:
    $ time find -type f -print0 | xx10 seq 1 20 | xx -P 4 echo “Greetings World”
    real 0m1.339s
    user 0m0.012s
    sys 0m0.212s

    $ time find -type f -print0 | xx10 seq 1 20 | xx echo “Greetings World”
    real 0m2.700s
    user 0m0.040s
    sys 0m0.216s

    Warning: know where your bottlenecks are, otherwise you may run it slower:

    $ time find -type f -print0 | xx10 -P 4 seq 1 20 | xx echo “Greetings World”
    real 0m2.962s
    user 0m0.024s
    sys 0m0.268s

    My useful aliases:
    alias x=”xargs” # x means regular xargs
    alias x0=”xargs -0″ # 0 means that the list is delimited by instead of spaces
    alias x1=”xargs -n1″ # 1 means that there should only be 1 argument per command
    alias x10=”xargs -0 -n1″
    alias x01=”xargs -0 -n1″
    alias xx=”xargs -I{}” # second x means use -I{}
    alias xx0=”xargs -0 -I{}”
    alias xx1=”xargs -n1 -I{}”
    alias xx10=”xargs -0 -n1 -I{}”
    alias xx01=”xargs -0 -n1 -I{}”

  4. joc

    This worked for me

    yes hello | head -5

  5. gogo

    @ joc

    That alone won’t work, unless all you want is to output the string “hello” 5 times. The command “yes ls | head -5″ will not produce a listing of the current directory but merely the following output:

    ls
    ls
    ls
    ls
    ls

    Instead, you have to pipe the repeated strings to another shell that would execute the said command, that is something like:

    yes ls | head -5 | bash

Leave a comment