1

Consider the following script.

#!/bin/bash

echo {00..99}
n=99
echo {00..$n}

The output of this script is:

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
{00..99}

The desired output is:

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

One solution which produces the desired output is

eval echo  {00..$n}

Unfortunately, this solution uses eval which I'd prefer to avoid if possible.

Does anyone know of a way to obtain the desired result using brace expansion but not eval?

merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • If you want to iterate over a variable-length sequence of integers, use a C-style for loop: `for ((i=00; i<100; i++)); do`. – chepner Oct 26 '15 at 12:54
  • Possible duplicate of [Bash: curly brace expansion with variable for mkdir](http://stackoverflow.com/questions/9337489/bash-curly-brace-expansion-with-variable-for-mkdir) – Benjamin W. Oct 26 '15 at 14:26

3 Answers3

3

From the bash manual:

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.

Given that variable expansion comes after brace expansion, and that there is no way to induce a different order of operations without using eval, I would have to conclude that no, there is no way to avoid using eval.

mooiamaduck
  • 2,066
  • 12
  • 13
1

Does anyone know of a way to obtain the desired without without eval?

You can use seq command,

seq -w -s ' ' 0 $n

Test:

sat $ seq -w -s " " 0 $n
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
sat
  • 14,589
  • 7
  • 46
  • 65
1

Not sure if this meets your requirements, as it doesn't use braces, but (with GNU seq at least) the following produces the desired output:

$ n=99
$ seq -f%02.0f -s' ' 00 "$n"
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

The "-f" option produces the zero-padding, and the "-d" uses spaces to separate, rather than newlines.

psmears
  • 26,070
  • 4
  • 40
  • 48
  • Thank you for the answer, but it solves the problem without addressing the underlying question. :) – merlin2011 Oct 26 '15 at 07:31
  • @merlin2011: Fair enough - but it would be worth updating your question to be clearer: since it currently says "Does anyone know of a way to obtain the desired without `eval`?", that can be taken as "How do I get the output a brace expansion would produce", rather than "I specifically want to use brace expansion" :) – psmears Oct 26 '15 at 08:43
  • Updated the question for clarity. Thanks for the note! :) – merlin2011 Oct 26 '15 at 09:08