Differences between revisions 4 and 5
Revision 4 as of 2008-04-11 17:38:45
Size: 2623
Editor: 82-71-12-170
Comment:
Revision 5 as of 2008-05-15 18:01:44
Size: 2987
Editor: GreyCat
Comment:
Deletions are marked like this. Additions are marked like this.
Line 6: Line 6:
Line 8: Line 7:
    # Bourne
Line 13: Line 13:
Line 14: Line 15:
Line 22: Line 22:
Line 23: Line 24:
Line 25: Line 25:
    for ((i=1; i<=10; i++))     # Bash 2 for-loop syntax     # Bash
for ((i=1; i<=10; i++))
Line 30: Line 31:
Line 31: Line 33:
{{{
   # Bash 3
   printf "%03d\n" {1..300}
}}}
Line 32: Line 38:
The KornShell has the {{{typeset}}} command to specify the number of leading zeros:
Line 33: Line 40:
   printf "%03d\n" {1..300} # Bash 3 brace expansion
}}}
The KornShell and KornShell93 have the {{{typeset}}} command to specify the number of leading zeros:

{{{
    # Korn
Line 42: Line 45:
Line 43: Line 47:
Line 47: Line 50:
Line 48: Line 52:
Line 52: Line 55:
Line 53: Line 57:
Line 55: Line 58:
   # POSIX
Line 57: Line 61:
Line 62: Line 67:
Line 64: Line 68:
   # Bourne
Line 72: Line 77:
Line 77: Line 83:
   printf "%03d\n" {$START..$END} | xargs -i% wget $LOCATION/%    # Bash
   # START and END are variables containing integers
   eval
printf '"%03d\n"' {$START..$END} | xargs -i% wget $LOCATION/%
Line 79: Line 87:
Or, in a slightly more general case:
Line 81: Line 88:
The `eval` is needed here because you cannot have variables in a brace expansion -- only constants. The extra quotes are required by the `eval` so that our `\n` isn't changed to an `n`.

A slightly more general case:
Line 82: Line 92:
   # Bash
Line 87: Line 98:

Personally, GreyCat likes the `for` loop version much better than the `eval`/`xargs` version.

Anchor(faq18)

How can I use numbers with leading zeros in a loop, e.g. 01, 02?

As always, there are different ways to solve the problem, each with its own advantages and disadvantages.

If there are not many numbers, BraceExpansion can be used:

    # Bourne
    for i in 0{1,2,3,4,5,6,7,8,9} 10
    do
        echo $i
    done

Output:

   00
   01
   02
   03
   [...]

This gets tedious for large sequences, but there are other ways, too. If you have the printf command (which is a Bash builtin, and is also POSIX standard), it can be used to format a number:

    # Bash
    for ((i=1; i<=10; i++))
    do
        printf "%02d " "$i"
    done

In Bash 3, you can use ranges inside brace expansion. Also, since printf will implicitly loop if given more arguments than format specifiers, you can simplify this enormously:

   # Bash 3
   printf "%03d\n" {1..300}

The KornShell has the typeset command to specify the number of leading zeros:

    # Korn
    $ typeset -Z3 i=4
    $ echo $i
    004

If the command seq(1) is available (it's part of GNU sh-utils/coreutils), you can use it as follows:

    seq -w 1 10

or, for arbitrary numbers of leading zeros (here: 3):

    seq -f "%03g" 1 10

Combining printf with seq(1), you can do things like this:

   # POSIX
   printf "%03d\n" $(seq 300)

(That may be helpful if your version of seq(1) lacks printf-style format specifiers. Since it's a nonstandard external tool, it's good to keep your options open.)

Be warned however that seq might be considered bad style, it's even mentioned in ["Don't Ever Do These"].

Finally, the following example works with any BourneShell derived shell to zero-pad each line to three bytes:

   # Bourne
   i=0
   while test $i -le 10
   do
       echo "00$i"
       i=`expr $i + 1`
   done |
       sed 's/.*\(...\)$/\1/g'

In this example, the number of '.' inside the parentheses in the sed command determines how many total bytes from the echo command (at the end of each line) will be kept and printed.

Now, since the number one reason this question is asked is for downloading images in bulk, you can use the printf command with xargs(1) and wget(1) to fetch files:

   # Bash
   # START and END are variables containing integers
   eval printf '"%03d\n"' {$START..$END} | xargs -i% wget $LOCATION/%

The eval is needed here because you cannot have variables in a brace expansion -- only constants. The extra quotes are required by the eval so that our \n isn't changed to an n.

A slightly more general case:

   # Bash
   for i in {1..100}; do
      wget "$prefix$(printf %03d $i).jpg"
      # other commands
   done

Personally, GreyCat likes the for loop version much better than the eval/xargs version.

BashFAQ/018 (last edited 2019-08-21 16:24:29 by GreyCat)