Reputation: 25
I have 2 different scripts doing basically the same: counting the subdirectories in the current directory:
c=0
ls -l | grep "^d" | while read zeile
do
c=`expr $c + 1`
echo $c
done
echo "Subdirs: $c"
and
c=0
while read zeile
do
c=`expr $c + 1`
echo $c
done < <(ls -l | grep "^d")
echo "Subdirs: $c"
My Problem is, that in the first version, "c" seems to lose it's value after the while-loop has finished.
The outputs
1)
1
2
3
Subdirs: 0
2)
1
2
3
Subdirs: 3
Can anyone of you explain to me, why this is happening?
Thanks in advance Alex
Upvotes: 2
Views: 251
Reputation: 359965
You should not use ls
in that way.
You should use a for loop and a glob to iterate over files or directories.
for f in *
do
if [[ -d $f ]]
then
(( c++ ))
fi
done
echo "Subdirs: $c"
or
for f in */
do
(( c++ ))
done
echo "Subdirs: $c"
Here's a hackish way:
arr=(*/); echo "Subdirs: ${#arr[@]}"
You will probably want to use nullglob
and dotglob
with any of the above. See BashFAQ/004 for more information.
Choroba is correct regarding the subshell issue.
Upvotes: 0
Reputation: 785008
If I have to count sub directories then I would use either of these 2 commands:
find . -regex ".\{2,\}" -maxdepth 1 -type d | wc -l
ls -l | grep "^d" | wc -l
Upvotes: 1
Reputation: 241828
In the first case, the assignment to c happens after the |
, i.e. in a subshell. You cannot change a variable in a parent shell from a subshell.
BTW, why do not you use let c++
instead of backquotes and expr?
Upvotes: 3