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 !
for i in seq 5; do echo Hello; done
> 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 =
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{}”
This worked for me
yes hello | head -5
@ 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