轉自http://kodango.com/generate-number-sequence-in-shell
Shell里怎么輸出指定的數字序列:
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
就不靈了。。。
怎么才能通過變量傳一個區間進來,讓他輸出數字序列?
查了下文檔,知道為什么{1..$END}
沒有效果了,看GNU的bash手冊是這么說的:
Brace expansion is erformed 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
當然,肯定有其它方法,只要你願意去思考。