Looping over directories in Bash

bash

Solution

Never ever parse the output of `ls` like this (Why you shouldn't parse the output of ls(1)).

Also, your syntax is wrong. You don't mean `()`, you mean `$()`.

That being said, to loop over directories starting with W you would do (or use the `find` command instead, depending on your scenario):

for path in /my/path/W*; do
    [ -d "${path}" ] || continue # if not a directory, skip
    dirname="$(basename "${path}")"
    do_stuff
done

As for the output you get from the evil ls-loop, it should not look like that. This is the expected output and demonstrates why you do not want to use ls in the first place:

$ find
.
./c
./a
./foo bar
./b

$ type ls
ls is hashed (/bin/ls)

$ for x in $(ls); do echo "${x}"; done
a
b
c
foo
bar

Problem

I have a fundamental question about how bash works, and a related practical question. Fundamental question: suppose I am in a directory that has three subdirectories: a, b, and c. hen the code ``` for dir in $(ls) do echo $dir done ``` spits out: ``` a b c a b c a b c ``` i.e, `dir` always stores a list of all of the files/directories in my `cwd`. My question is: why in the world would this be convenient? In my opinion it is far more useful and intuitive to have `dir` store each element at a time, i.e I would want to have output ``` a b c ``` Also, as per one of the answers - it is wrong to use `for dir in $(ls)`, but when I use `for dir in $(ls -l)` I get even more copies of `a b c` (more than there are directories/files in the cwd). Why is that? My second question is practical: how do I loop over all the directories (not files!) in my `cwd` that start with capital W? I started with ``` for dir in `ls -l W*` ``` but this fails because a) the reason in question 1 and b) because it doesn't exclude files. Suggestions appreciated.

Original source

Related problems