help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: case statement with non-consecutive numbers


From: Greg Wooledge
Subject: Re: case statement with non-consecutive numbers
Date: Thu, 15 Apr 2021 16:25:37 -0400

On Thu, Apr 15, 2021 at 10:09:12PM +0200, pauline-galea@gmx.com wrote:
> 
> I have a related question, if I could ask it.  It is about the
> 'for' construct.  What are the rules for constructing ranges
> and individual numbers for loops that could be equivalent to
> 
> [1-5]|7|21-35)

for VAR in WORDS; do CMDS; done

You can put any WORDS you like, and you can use globs here.  If you
use globs here, they will be expanded to actual filenames (pathname
expansion).

So, you could do a loop like this:

for f in *Episode' '[1-4].*; do
 ...

And this glob would expand to "Scandal - Episode 1.mp4" but not
"Scandal - Episode 8.mp4".  Of course, those files must already exist.
You're looping over existing files.

If you simply want a loop that counts (iterating over numbers, without
any file system lookups), there are a few approaches you can use.

In the simplest cases, you can use a brace expansion:

for i in {1..10}; do
 ...

The brace expansion {1..10} is equivalent to 1 2 3 4 5 6 7 8 9 10.  It's
exactly the same as typing them all out yourself, except it looks nicer
to humans.

If you want a longer loop, you can use the "C-style for":

for ((i=1; i <= 1000; i++)); do
 ...

This one counts from 1 to 1000, without having to generate the entire list
of numbers 1 2 3 4 5 6 7 8 9 ... 999 1000 in memory all at once (which is
what a brace expansion would do).

But for some reason you wanted to iterate over a discontinuous list of
integers.  Let's say there's a gap, and you want to count from 1 to 100
except that you want to skip over 11 and 37.  One way to do it would be
to hard-code those exceptions inside the body:

for i in {1..100}; do
  case $i in 11|37) break;; esac
  ...
done

In the example you gave, there is a large gap between 7 and 21.  You could
hard-code all of those exceptions, but it starts to get awkward that way.
So, for this particular problem, we might try this instead:

for i in {1..5} 7 {21..35}; do
 ...

This is equivalent to typing out 1 2 3 4 5 7 21 22 23 24 25 26 ... 34 35.
You could also do that, although most people would find that unpleasant.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]