How do I iterate over a range of numbers defined by variables in Bash?

后端 未结 20 1950
予麋鹿
予麋鹿 2020-11-21 05:19

How do I iterate over a range of numbers in Bash when the range is given by a variable?

I know I can do this (called \"sequence expression\" in the Bash documentatio

20条回答
  •  南方客
    南方客 (楼主)
    2020-11-21 05:43

    If you want to stay as close as possible to the brace-expression syntax, try out the range function from bash-tricks' range.bash.

    For example, all of the following will do the exact same thing as echo {1..10}:

    source range.bash
    one=1
    ten=10
    
    range {$one..$ten}
    range $one $ten
    range {1..$ten}
    range {1..10}
    

    It tries to support the native bash syntax with as few "gotchas" as possible: not only are variables supported, but the often-undesirable behavior of invalid ranges being supplied as strings (e.g. for i in {1..a}; do echo $i; done) is prevented as well.

    The other answers will work in most cases, but they all have at least one of the following drawbacks:

    • Many of them use subshells, which can harm performance and may not be possible on some systems.
    • Many of them rely on external programs. Even seq is a binary which must be installed to be used, must be loaded by bash, and must contain the program you expect, for it to work in this case. Ubiquitous or not, that's a lot more to rely on than just the Bash language itself.
    • Solutions that do use only native Bash functionality, like @ephemient's, will not work on alphabetic ranges, like {a..z}; brace expansion will. The question was about ranges of numbers, though, so this is a quibble.
    • Most of them aren't visually similar to the {1..10} brace-expanded range syntax, so programs that use both may be a tiny bit harder to read.
    • @bobbogo's answer uses some of the familiar syntax, but does something unexpected if the $END variable is not a valid range "bookend" for the other side of the range. If END=a, for example, an error will not occur and the verbatim value {1..a} will be echoed. This is the default behavior of Bash, as well--it is just often unexpected.

    Disclaimer: I am the author of the linked code.

提交回复
热议问题