我偶尔会像这样运行bash命令行:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
some_command
连续运行多次-在这种情况下为10次。
通常some_command
,实际上实际上是命令链或管道。
有更简洁的方法吗?
zsh
有repeat 10 do some_command; done
。
sh: 1: [[: not found
。
我偶尔会像这样运行bash命令行:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
some_command
连续运行多次-在这种情况下为10次。
通常some_command
,实际上实际上是命令链或管道。
有更简洁的方法吗?
zsh
有repeat 10 do some_command; done
。
sh: 1: [[: not found
。
Answers:
for run in {1..10}
do
command
done
或作为希望轻松复制和粘贴的人员的单线:
for run in {1..10}; do command; done
for (n=0;n<k;n++))
可能会更好;我怀疑{1..k}
会用所有用空格分隔的整数来实现一个字符串。
n=15;for i in $(seq -f "%02g" ${n});do echo $i; done 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
使用常量:
for ((n=0;n<10;n++)); do some_command; done
使用变量(可以包含数学表达式):
x=10; for ((n=0; n < (x / 2); n++)); do some_command; done
x=10
for ((n=0; n < $x; n++));
for run in {1..10}; do echo "on run $run"; done
n
已经设置为特定值怎么办?for (( ; n<10; n++ ))
不工作/编辑:最好可能使用其他答案喜欢的一个while (( n++...
一个
破解它的另一种简单方法:
seq 20 | xargs -Iz echo "Hi there"
运行echo 20次。
注意,seq 20 | xargs -Iz echo "Hi there z"
将输出:
嗨1
嗨2
...
seq 20
)
seq 20 | xargs -I{} echo "Hi there {}"
z
不是一个好的占位符,因为它很常见,可以在命令文本中用作常规文本。使用{}
会更好。
seq
吗?这样它只会打印Hi there
20次(没有数字)?编辑:只使用-I{}
,然后{}
在命令中没有任何内容
IIIII
然后看起来不错,例如:seq 20 | xargs -IIIIII timeout 10 yourCommandThatHangs
如果您使用的是zsh shell:
repeat 10 { echo 'Hello' }
其中10是重复命令的次数。
repeat 10 { !! }
使用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)。您会用它来爱您。
-j1 -N0
是关闭并行 ????
some_command
在无参数的情况下连续运行1000次?并且:您能说的比那短parallel -j1 -N0 some_command ::: {1..1000}
吗?
repeat.sh repeatcount some_command
。为了在shell脚本中实现,我可能会使用parallel
,如果它已经安装在机器上(可能不是)。或者我可能倾向于使用xargs,因为当不需要重定向时,这似乎是最快的some_command
。
parallel -N0 -j1 --retries 4 --results outputdir/ some_command
bash配置文件中的一个简单功能(~/.bashrc
经常)可以很好地工作。
function runx() {
for ((n=0;n<$1;n++))
do ${*:2}
done
}
这样称呼它。
$ runx 3 echo 'Hello world'
Hello world
Hello world
Hello world
do ${*:2}
添加了eval do eval ${*:2}
来确保它适用于运行不是以可执行文件开头的命令,而不仅仅是这样做。例如,如果您想在运行诸如之类的命令之前设置环境变量SOME_ENV=test echo 'test'
。
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
and while
循环。当然,这仅适用于单个命令。如果您需要在循环的每次迭代中执行多个命令,则它与传递循环一样快,甚至更快。sh -c 'command1; command2; ...'
给xargs
该-P1
也可以改变,比方说,-P8
产卵并行8个流程,以获得速度的另一大助力。
我不知道为什么GNU并行这么慢。我以为它可以与xargs相提并论。
您的示例的另一种形式:
n=0; while (( n++ < 10 )); do some_command; done
首先,您可以将其包装在一个函数中:
function manytimes {
n=0
times=$1
shift
while [[ $n -lt $times ]]; do
$@
n=$((n+1))
done
}
像这样称呼它:
$ manytimes 3 echo "test" | tr 'e' 'E'
tEst
tEst
tEst
tr
这里是误导,它的工作的输出manytimes
,没有echo
。我认为您应该从样本中删除它。
xargs和seq将有所帮助
function __run_times { seq 1 $1| { shift; xargs -i -- "$@"; } }
风景 :
abon@abon:~$ __run_times 3 echo hello world
hello world
hello world
hello world
如果可以定期执行此操作,则可以运行以下命令无限期地每1秒运行一次。您可以放置其他自定义检查以运行n次。
watch -n 1 some_command
如果希望对更改进行视觉确认,请--differences
在ls
命令前附加。
根据OSX手册页,
--cumulative选项突出显示“粘滞”,显示所有已更改位置的运行显示。-t或--no-title选项将关闭显示顶部的间隔,命令和当前时间的标题,以及以下空白行。
Linux / Unix手册页可以在这里找到
所有现有的答案似乎都是require bash
,并且不适用于标准的BSD UNIX /bin/sh
(例如,ksh
在OpenBSD上))。
以下代码可在任何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循环可能是正确的方法,但这是一个有趣的选择:
echo -e {1..10}"\n" |xargs -n1 some_command
如果您需要迭代号作为调用的参数,请使用:
echo -e {1..10}"\n" |xargs -I@ echo now I am running iteration @
编辑:正确地评论说,上面给出的解决方案仅在简单的命令运行(没有管道等)下才能顺利运行。您可以随时使用sh -c
做更复杂的事情,但不值得。
我通常使用的另一种方法是以下功能:
rep() { s=$1;shift;e=$1;shift; for x in `seq $s $e`; do c=${@//@/$x};sh -c "$c"; done;}
现在您可以将其称为:
rep 3 10 echo iteration @
前两个数字给出范围。在@
将得到翻译为迭代次数。现在,您也可以将其与管道一起使用:
rep 1 10 "ls R@/|wc -l"
与给你在目录R1 .. R10中的文件数。
rep 1 2 touch "foo @"
不会创建两个文件“ foo 1”和“ foo 2”;而是创建三个文件“ foo”,“ 1”和“ 2”。可能有一种使用printf
和来获得正确报价的方法%q
,但是要正确地将一个任意的单词序列引用到单个字符串中并传递给它,将非常棘手sh -c
。
rep
在.bashrc
进一步调用变得更为简洁。
let ++n
代替n=$((n+1))
(少3个字符)。