Variables in bash seq replacement ({1..10})
有可能做这样的事情:
1 2 3 4 5
| start=1
end=10
echo {$start..$end}
# Ouput: {1..10}
# Expected: 1 2 3 ... 10 (echo {1..10}) |
在bash中,大括号扩展在变量扩展之前发生,因此这不可能直接实现。
相反,使用算术for循环:
1 2 3 4 5 6
| start=1
end=10
for ((i=start; i<=end; i++))
do
echo"i: $i"
done |
OUTPUT
1 2 3 4 5 6 7 8 9 10
| i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
i: 10 |
-
问题的关键不在于循环中的数字应该是变量吗?
-
@Letharion感谢您的评论,这是一年多的答案,但自从您评论后我更新了我的答案并提供了更好的选择。请检查。
-
输出应该是1 2 3 4 5 6 7 8 9 10?
-
它是可能的,但它有点难看,因为一个开始另一个shell在大括号扩展之前进行变量扩展:start=1;end=10;for i in $(bash -c"echo {$start..$end}");do echo $i;done
你应该考虑使用seq(1)。 你也可以使用eval:
1
| eval echo {$start..$end} |
这是seq
-
我的shell中没有seq命令
-
@Tyilo现在我明白了。
-
而且seq也被弃用了
-
@Tylio是吗?!我不知道。为什么要弃用?
-
@cnicutar这里:cyberciti.biz/faq/bash-for-loop
-
@Tyilo我同意一个人应该赞成内部命令/结构而不是外部程序。但是如果我使用不支持该语法的东西会发生什么呢?比如dash?还是ash?还是tcsh?
-
@Tyilo你在使用什么shell / OS?的Solaris?我从未见过seq在任何Linux发行版上都没有出现过。事实上,它甚至在GNU coreutils中:gnu.org/s/coreutils/manual/html_node/seq-invocation.html
-
@opsguy FreeBSD也没有它(尽管它在ports中)。
-
@cnicutar哇,很高兴知道,我想我总是在bsd上自动安装coreutils。谢谢你的提示!
-
我使用的是Mac OS X 10.6.7
-
@opsguy coreutils!= POSIX标准。当然,它存在于Linux中,但世界上有更多的操作系统。
-
对于它的价值,"弃用"并不意味着"不可取"
-
使用eval在这里和大多数其他地方一样可怕,不习惯它或者你会发现自己有一天会留下命令注入漏洞
你必须使用eval:
1
| eval echo {$start..$end} |
-
这就像用手提钻敲钉子一样。这很危险(从字面上看,如果你的任何值来自不受信任的输入,会引入潜在的shell注入漏洞),而不是正确的工具。 for ((i=start; i。
如果你没有seq,你可能想要坚持使用普通for循环
1
| for (( i=start; i<=end; i++ )); do printf"%d" $i; done; echo"" |
你是积极的,它是BASH吗? ZSH以您想要的方式处理这个问题。 这在BASH中不起作用,因为大括号扩展发生在任何其他扩展类型之前,例如变量扩展。 所以你需要使用另一种方法。
你需要结合括号和变量扩展的任何特殊原因? 也许对您的问题采用不同的方法可以避免对此问题的需求。
我通常只是这样做:
-
看看我对cnicutar的回答的评论
-
seq是一个非标准工具(字面意思,未在POSIX中指定)。
-
更不用说seq是非标准的,但echo +命令替换只是一个愚蠢的组合。
-
如果你需要添加换行符,请不要@ilkkachu。
-
@BrunoBronosky,更大的区别是,不带引号的命令替换将空格折叠为单个空格(除非IFS从默认值更改)。所以你得到的数字都在同一行,而不是像seq那样默认的一行。但如果你想要,你可以使用seq -w ' ' 1 10。另一方面,如果引用命令替换,则echo"$(seq 1 10)"和seq 1 10具有完全相同的输出。命令替换条跟踪换行符(有一个),echo加回一个。
使用-s
例如:
seq -s''1 10
输出:1 2 3 4 5 6 7 8 9 10