搜索
linux - Shell里怎么输出指定的数字序列
怪我咯
怪我咯 2017-04-17 11:08:09
[Linux讨论组]
for i in {1..5}; do echo $i; done

可以输出

1
2
3
4
5

但是如果

END=5
for i in {1..$END}; do echo $i; done

就不灵了。。。
怎么才能通过变量传一个区间进来,让他输出数字序列?

怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(5)
阿神

试下这个
END=5;for i in $(seq -s' ' 1 $END);do echo $i;done

还有这个
END=5;for i in $(eval echo {1..$END});do echo $i;done

黄舟

为什么{1..$END}这种方式不可以,我也说不上什么原因,这样做的结果并没有得到期望的数值序列:

update
查了下文档,知道为什么{1..$END}没有效果了,看GNU的bash手册是这么说的:

Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces. To avoid conflicts with parameter expansion, the string ‘${’ is not considered eligible for brace expansion.

也就是说Brace expansion是在其它所有类型的展开之前处理的包括参数和变量展开,因此{1..$END}就是{1..$END},原封不动,不知道你能不能理解?或许你将{1..$END}看成{1..END}好了,因为这里$END只是一个字符串而已。

另外一方面,GNU的bash手册也说明了这个语法的使用方法:

A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters, and incr, an optional increment, is an integer. When integers are supplied, the expression expands to each number between x and y, inclusive....When characters are supplied, the expression expands to each character lexicographically between x and y, inclusive. Note that both x and y must be of the same type. When the increment is supplied, it is used as the difference between each term. The default increment is 1 or -1 as appropriate.

从上面可以看出{x..y}的限制条件是:1) 整数或者单个字符; 2)两者要是同一个类型。

回到我们的例子,{1..$END}x=1, y=$END,前者是整数,后者是字符串,不符合以上任何一个条件,所以也就不展开了。

ABS文档里面也有例子介绍这个语法的使用方法,中间也提到这点。

$ for i in {1..$END}; do echo $i; done
{1..5}

从上面的结果可以看出,只是显示了{1..5}这个结果。

如果要得到数值序列,有很多种方法。第一种是用seq start end这种形式来替换{start..end},如:

$ for i in `seq 1 $END`; do echo $i; done

当然如果你一定要用{start..end},可以用eval命令:

$ for i in `eval echo {1..$END}`; do echo $i; done

这里eval echo {1..$END}后的结果为{1..5}。

最直观的是用循环了:

$ for ((i=0;i<$END;i++)) do echo $i; done
怪我咯
for ((i=0;i<$END;i++)); do echo $i; done
天蓬老师

END=5

改成

declare -i END=5

就可以了

迷茫

答了但好像没有说明为什么.

{1..5} 是Shell的展开, 最后成了 1 2 3 4 5
而当你把$END放在{}之内时 $END没有先被eval而成为数子5以致没有展开的效果.
所以可以用eval的方法再把{1..5}展开一次, 或不把$END放进{}的方法

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号