我偶尔会像这样运行bash命令行:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
在一行中运行some_command多次——在本例中为10次。
通常some_command实际上是一个命令链或管道。
有没有更简洁的方法呢?
我偶尔会像这样运行bash命令行:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
在一行中运行some_command多次——在本例中为10次。
通常some_command实际上是一个命令链或管道。
有没有更简洁的方法呢?
当前回答
Xargs速度很快:
#!/usr/bin/bash
echo "while loop:"
n=0; time while (( n++ < 10000 )); do /usr/bin/true ; done
echo -e "\nfor loop:"
time for ((n=0;n<10000;n++)); do /usr/bin/true ; done
echo -e "\nseq,xargs:"
time seq 10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nyes,xargs:"
time yes x | head -n10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nparallel:"
time parallel --will-cite -j1 -N0 /usr/bin/true ::: {1..10000}
在现代64位Linux上,给出:
while loop:
real 0m2.282s
user 0m0.177s
sys 0m0.413s
for loop:
real 0m2.559s
user 0m0.393s
sys 0m0.500s
seq,xargs:
real 0m1.728s
user 0m0.013s
sys 0m0.217s
yes,xargs:
real 0m1.723s
user 0m0.013s
sys 0m0.223s
parallel:
real 0m26.271s
user 0m4.943s
sys 0m3.533s
这是有意义的,因为xargs命令是一个单独的本机进程,多次生成/usr/bin/true命令,而不是在Bash中解释的for和while循环。当然,这只适用于单个命令;如果你需要在每次循环迭代中执行多个命令,它将和传递sh -c 'command1;command2;...'到xargs
也可以将-P1改为-P8,以并行生成8个进程,从而获得另一个巨大的速度提升。
我不知道GNU并行为什么这么慢。我本以为它可以与xargs相媲美。
其他回答
使用GNU Parallel你可以做到:
parallel some_command ::: {1..1000}
如果您不希望将数字作为参数,并且一次只运行一个作业:
parallel -j1 -N0 some_command ::: {1..1000}
观看介绍视频快速介绍: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
浏览本教程(http://www.gnu.org/software/parallel/parallel_tutorial.html)。命令行 用爱你换吧。
所有现有的答案似乎都需要bash,并且不能使用标准的BSD UNIX /bin/sh(例如,OpenBSD上的ksh)。
下面的代码可以在任何BSD上运行:
$ echo {1..4}
{1..4}
$ seq 4
sh: seq: not found
$ for i in $(jot 4); do echo e$i; done
e1
e2
e3
e4
$
使用常量:
for ((n=0;n<10;n++)); do
some_command;
done
使用变量(可以包括数学表达式):
x=10; for ((n=0; n < (x / 2); n++)); do some_command; done
Xargs速度很快:
#!/usr/bin/bash
echo "while loop:"
n=0; time while (( n++ < 10000 )); do /usr/bin/true ; done
echo -e "\nfor loop:"
time for ((n=0;n<10000;n++)); do /usr/bin/true ; done
echo -e "\nseq,xargs:"
time seq 10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nyes,xargs:"
time yes x | head -n10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nparallel:"
time parallel --will-cite -j1 -N0 /usr/bin/true ::: {1..10000}
在现代64位Linux上,给出:
while loop:
real 0m2.282s
user 0m0.177s
sys 0m0.413s
for loop:
real 0m2.559s
user 0m0.393s
sys 0m0.500s
seq,xargs:
real 0m1.728s
user 0m0.013s
sys 0m0.217s
yes,xargs:
real 0m1.723s
user 0m0.013s
sys 0m0.223s
parallel:
real 0m26.271s
user 0m4.943s
sys 0m3.533s
这是有意义的,因为xargs命令是一个单独的本机进程,多次生成/usr/bin/true命令,而不是在Bash中解释的for和while循环。当然,这只适用于单个命令;如果你需要在每次循环迭代中执行多个命令,它将和传递sh -c 'command1;command2;...'到xargs
也可以将-P1改为-P8,以并行生成8个进程,从而获得另一个巨大的速度提升。
我不知道GNU并行为什么这么慢。我本以为它可以与xargs相媲美。
这有点天真,但这是我通常能立即想到的:
for i in 1 2 3; do
some commands
done
和@joe- kobberg的回答很相似。他的更好,特别是当你需要很多重复的时候,只是更难记住其他语法,因为在过去的几年里,我不经常使用bash。我的意思是至少不是写脚本。