1

I am trying to run the next code on bash. It is suppose to work but it does not. Can you help me to fix it? I am starting with programming. The code is this:

for i in {1:5}
do
   cd path-to-folder-number/"$i"0/
   echo path-to-folder-number/"$i"0/
done

EXAMPLE

I want to iterate over folders which have numbers (10,20..50), and so it changes directory from "path-to-folder-number/10/" to "path-to-folder-number/20/" ..etc

I replace : with .. but it is not working yet. When the script is applied i get:

can't cd to path-to-folder-number/{1..5}0/ 
  • 3
    for i in {1..5}; do echo $i; done – John C May 05 '17 at 02:13
  • @JohnC i did that but i get: can't cd to path-to-folder-number/{1..5}0/ I change a little the script, please see the post again –  May 05 '17 at 02:30
  • 3
    @santimirandarp That suggests you aren't using bash, but some other shell that doesn't support brace expansions. What's the script's shebang line and how are your running it? – Gordon Davisson May 05 '17 at 03:04
  • @Gordon Davisson I am running it as sh script.sh..maybe is that wrong ? –  May 05 '17 at 03:33
  • I had not understand what you mean with "shebang" line. Can it be "#!/bin/sh"? –  May 05 '17 at 03:41
  • If you have the shebang line (yes, the one that starts with `#!`) set to `#!/bin/sh` and call the script like this: `./script` *or* call the script like `sh script` (no matter what the shebang line says), then you're either not using Bash or Bash in POSIX mode, see http://stackoverflow.com/questions/5725296/difference-between-sh-and-bash – Benjamin W. May 05 '17 at 04:28
  • Also, it has to be `{1..5}`, not `{1:5}`, but according to the error message that's what you used. You should fix the code. – Benjamin W. May 05 '17 at 04:29

4 Answers4

0

For up ranges the syntax is:

for i in {1..5}
do
   cd path-to-folder-number/"$i"0/
   echo $i
done

So replace the : with ..

ifma
  • 3,673
  • 4
  • 26
  • 38
  • I think you are right, but it is not working,**i obtain:** can't cd to path-to-folder-number/{1..5}0/ I change a little the script, please see the post again –  May 05 '17 at 02:25
0

To get exactly what you want you can use this:

for i in 10 {20..50}
do
    echo $i
done
John C
  • 4,276
  • 2
  • 17
  • 28
  • I think OP wants 10, 20, 30, 40 and 50... not 10, 20, 21, etc up to 49, 50... in other words `{1..5}0` – Sundeep May 05 '17 at 02:23
  • You are right, but i reformulate the question, i think it changed, isn't it? –  May 05 '17 at 02:23
0

I think there are three problems here: you're using the wrong shell, the wrong syntax for a range, and if you solved those problems you may also have trouble with successive cds not doing what you want.

  • The shell problem is that you're running the script with sh instead of bash. On some systems sh is actually bash (but running in POSIX compatibility mode, with some advanced features turned off), but I think on your system it's a more basic shell that doesn't have any of the bash extensions.

    The best way to control which shell a script runs with is to add a "shebang" line at the beginning that says what interpreter to run it with. For bash, that'd be either #!/bin/bash or #!/usr/bin/env bash. Then run the script by either placing it in a directory that's in your $PATH, or explicitly giving the path to the script (e.g. with ./scriptname if you're in the same directory it's in). Do not run it with sh scriptname, because that'll override the shebang and use the basic shell, and it won't work.

    (BTW, the name "shebang" comes from the "#!" characters the line starts with -- the "#" character is sometimes called "sharp", and "!" is sometimes called "bang", so it's "sharp-bang", which gets abbreviated to "shebang".)

  • In bash, the correct syntax for a range in a brace expansion is {1..5}, not {1:5}. Note that brace expansions are a bash extension, which is why getting the right shell matters.

  • Finally, a problem you haven't actually run into yet, but may when you get the first two problems fixed: you cd to path-to-folder-number/10/, and then path-to-folder-number/20/, etc. You are not cding back to the original directory in between, so if the path-to-folder-number is relative (i.e. doesn't start with "/"), it's going to try to cd to path-to-folder-number/10/path-to-folder-number/20/path-to-folder-number/30/path-to-folder-number/40/path-to-folder-number/50/.

    IMO using cd in scripts is generally a bad idea, because there are a number of things that can go wrong. It's easy to lose track of where the script is going to be at which point. If any cd fails for any reason, then the rest of the script will be running in the wrong place. And if you have any files specified by relative paths, those paths become invalid as soon as you cd someplace other than the original directory.

    It's much less fragile to just use explicit paths to refer to file locations within the script. So, for example, instead of cd "path-to-folder-number/${i}0/"; ls, use ls "path-to-folder-number/${i}0/".

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
0

You can also use seq :

for i in $(seq 10 10 50);  do
   cd path-to-folder-number/$i/
   echo path-to-folder-number/$i/
done
Tiago Lopo
  • 7,619
  • 1
  • 30
  • 51