3 ms·
You can use brace expansion to avoid calling out to seq in a subshell (`{1..5}` expands to `1 2 3 4 5`)
by LanternLight83 4y ago
You can use brace expansion to avoid calling out to seq in a subshell (`{1..5}` expands to `1 2 3 4 5`)
- 0xbadcafebee 4y agoAwesome, thanks!! Just found the section of the man page, looks like a pretty feature-filled expansion technique: 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 sup- plied, the expression expands to each number between x and y, inclusive. Supplied integers may be prefixed with 0 to force each term to have the same width. When either x or y begins with a zero, the shell attempts to force all generated terms to contain the same number of digits, zero-padding where necessary. When characters are supplied, the expres- sion expands to each character lexicographically between x and y, inclusive, using the default C locale. 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. ...although I just tested it, and the increment and 0-padding only work in non-interactive mode ='(
- hddqsb 4y ago> ...although I just tested it, and the increment and 0-padding only work in non-interactive mode ='( Works for me... $ echo $0 # determine current shell (alternative: "ps -p $$") bash $ echo {01..100..20} 001 021 041 061 081 But note that `{x..y}` has a major limitation: it doesn't support variables. Example: $ n=5 $ echo {1..$n} {1..5} # intended output: 1 2 3 4 5 The `for ((...))` syntax mentioned by @zazaulola supports variables (it works in bash and zsh). For completeness, here is a POSIX sh approach that doesn't require `seq` (in fact I notice this is what your "Uber Fancy" version uses internally): i=1 while [ "$i" -le 5 ]; do echo "$i" i="$((i+1))" done (but note that `continue` won't work properly).
- bheadmaster 4y agoYou can always do double eval for variables: var=1234 echo `echo {1..$var}`
- 0xbadcafebee 4y agoYup, which you could also write as eval echo {1..$var} . The second argument's variable is being interpolated as if it's a quoted string, before it gets passed to eval, so eval is actually seeing "{1..1234}" and not doing the interpolation itself (because it wouldn't, because the variable isn't valid in a range). This should prevent the need for a subshell and the second echo call. With an array: var=12 declare -a array=() eval "array=( {01..$var} )" echo "${array[@]}" # 01 02 03 04 05 06 07 08 09 10 11 12
- 0xbadcafebee 4y agoAhhh, my login shell is bash v3 (friggin' MacOS!) but my PATH has bash v5! On Bash v5 it works interactively! (probably v4+ too)