问:
当范围由变量给出时,如何在Bash中遍历这一范围内的数字?
我知道我可以这样做(在 Bash 文档中称为“序列表达式”):
代码语言:bash复制for i in {1..5}; do echo $i; done
它会输出:
代码语言:bash复制1
2
3
4
5
然而,我该如何用变量替换范围的任意一个端点呢?以下这种方法无法工作:
代码语言:bash复制END=5
for i in {1..$END}; do echo $i; done
这会输出:
代码语言:bash复制{1..5}
答:
提问者代码不起作用的原因是花括号扩展在任何其他扩展之前执行,且其他扩展中具有特殊含义的任何字符都会在结果中保留下来。这是一种严格的文本处理。Bash 不会对扩展的上下文或者花括号之间的文本应用任何语法解释。换句话说,花括号扩展只是简单地基于文本的替换,它不会根据周围的语法环境或者花括号内部的文本进行复杂的分析或解析。这种方式确保了扩展的过程快速且不依赖于特定的语境。
方法一 使用 seq 命令
代码语言:javascript复制for i in $(seq 1 $END); do echo $i; done
优点是简单好记。
方法二 使用 Bash 内置的算术计算
代码语言:javascript复制typeset -i i END
END=5
for ((i=1;i<=END;i )); do
echo $i
done
for ((expr1;expr2;expr3));
结构的工作方式与 C 和类似语言中的for (expr1;expr2;expr3)
一样,并且像其他((expr))
情况一样,Bash 将它们视为算术表达式来处理。 这种方式避免了大型列表的内存开销,以及对 seq 的依赖。
参考文档:
- stackoverflow question 169511
- https://www.gnu.org/software/bash/manual/bash.html#Brace-Expansion
相关阅读:
- 如何用Bash遍历文本文件的每一行
- 如何将一个大的文本文件拆分为行数相等的小文件
- 在bash中:-(冒号破折号)的用法
- 在Bash中如何从字符串中删除固定的前缀/后缀