Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting if in a for loop

Tags:

I'm fairly new to bash scripts, so this is probably a stupid syntax error, but why is this code not working?

for x in $(ls) do   if [ -d $x ]   then   echo $x   fi done 

The separate for and if section work fine on their own, but this produces no output.

like image 289
James Jenkinson Avatar asked Aug 19 '12 21:08

James Jenkinson


People also ask

Can you nest an if statement in a for loop?

You can nest If statements inside For Loops. For example you can loop through a list to check if the elements meet certain conditions. You can also have a For Loop inside another For loop.

Can you nest a for loop in an if statement in C?

nested-if in C/C++Yes, both C and C++ allow us to nested if statements within if statements, i.e, we can place an if statement inside another if statement.

Can you nest a for loop in a for loop?

Yes you can use the same counter variable name for an inner for loop as for the outer for loop.

Can you have nested for loops?

Nested Loops The placing of one loop inside the body of another loop is called nesting. When you "nest" two loops, the outer loop takes control of the number of complete repetitions of the inner loop. While all types of loops may be nested, the most commonly nested loops are for loops.


1 Answers

Two things. Never use ls to iterate files, and quote parameter expansions "$x". The for and if syntax itself is correct. I prefer to put the do and then on the same line though

for file in *; do     if [[ -d "$file" ]]; then         echo "$file is a directory"     elif [[ -f "$file" ]]; then         echo "$file is a regular file"     fi done 

For learning bash, I recommend reading http://mywiki.wooledge.org/BashGuide most other tutorials and guides are unfortunately not very good.

The reason for not doing for x in $(ls) to iterate files is because for iterates words and ls outputs lines with filenames. if those filenames happen to contain whitespace, those filenames will be split up further into words, so you'll be iterating the words of the filenames, not the filenames. Obviously, for the simple cases that works, but why use a half-working solution when there's a shorter and more elegant way that handles all cases?

With for x in * the shell replaces the * with all filenames matching that pattern in the current directory (called pathname expansion), and each filename will be a separate word so it will work no matter what characters the filename contains. Filenames can contain any character (including newlines), except / and the NUL byte (\0).

See http://mywiki.wooledge.org/ParsingLs for more on that.

As for using [[ vs [. [ is a command inherited from the bourne shell, used to test strings, files and numbers. Bash has added a more powerful [[ keyword that can do everything [ can and more. If you're writing an sh script, you must use [, but in bash scripts you should use the more powerful [[ and (( syntaxes. See http://mywiki.wooledge.org/BashFAQ/031 for more about the difference between [ and [[.

like image 137
geirha Avatar answered Sep 30 '22 07:09

geirha