我在脚本中有以下内容:
#!/usr/bin/env bash
...
for i in {1..$N}
<loop content>
Run Code Online (Sandbox Code Playgroud)
以上不起作用,仅在i具有值的地方执行一次{1..5}
(如果5作为参数提供)。
如果我将上述内容替换为:
for i in $(seq 1 1 $N)
Run Code Online (Sandbox Code Playgroud)
..然后事情按预期工作。这是为什么?
Sté*_*las 10
{1..8}是括号扩展的形式通过引入zsh并通过最新版本的支持bash和ksh93。在bash,它很早就完成了。特别是,它是在之前完成的变量扩展。
虽然{1..8}有效,但{1..$N}不是因为$N不是十进制数,而是两个字符$,N没有一个是十进制数字。
即使这样有效,那也不会很有效率。shell 必须在内存中分配一个由数字 1 到$N. 如果$N是 10 9,那将意味着分配千兆字节的内存。
$(seq "$N")效率更低。首先,它不便携。seq是一个非标准的 GNU 命令。然后执行$(seq "$N")意味着启动一个新进程,seq在其中执行,shell 通过管道读取其输出并将其存储在内存中,然后拆分该列表(根据$IFS)并尝试对其执行文件名生成。
还必须为由拆分和通配生成的列表分配空间。
一种更有效的方法是使用ksh for (( ))循环样式(也得到了支持bash并zsh持续了几十年)。
for ((i = 1; i <= N; i++)); do
<loop content>
done
Run Code Online (Sandbox Code Playgroud)
或者简单地以可移植和标准的方式编写它,因此您甚至不必使用bash,并且可以使用您的(可能更快/更精简)系统的sh:
i=1
while [ "$i" -le "$N" ]; do
<loop content>
i=$(($i + 1))
done
Run Code Online (Sandbox Code Playgroud)
或者,也许您可以通过完全避免循环来以 shell 方式执行更多操作。但我们需要知道你最终想做什么来帮助那里。
| 归档时间: |
|
| 查看次数: |
32320 次 |
| 最近记录: |