I was trying to write a bash script for counting the number of files and the number of directories of the local directory. This was my first try:
#!/bin/bash
files=0
dir=0
for file in `ls`
do
if [ -d $file ]
then
dir=$(($dir+1))
else
files=$(($files+1))
fi
done
echo "files=$files, direcotries=$dir"
However, the for
command is not iterating over the names of files and directories as I would expect. If the name of the file ou directory has spaces, this does not work well. When there are spaces in the names, the variable "file" assumes the value of each of the words in the file (or directory) name.
Is there any way to do this?
Use a wild card:
for file in *; do …; done
. That keeps the spaces in the names correct. Considershopt -s nullglob
too. Neither your code nor my suggestion lists names starting with a dot.
.Also, use
if [ -d "$file" ]
with double quotes around the variable value to avoid spacing problems.Hence:
In Bash, there are also other ways of writing the arithmetic, such as
((files++))
.I think that Jonathan Leffler's answer is exactly what you need.
An alternative that shows the power of bash arrays and eliminates the need for loops:
This works as follows:
dirs=(*/)
creates an array of the names of the directories.ndir="${#dirs[@]}"
counts the number of directories.files=(*)
creates an array of the names of all files and directories.nfile=$(( "${#files[@]}" - ndir))
computes the number of files by taking the number of elements offiles
and subtracting from that the number of directories.echo "files=$nfile, directories=$ndir"
prints out the results.This will only work in a shell, like bash, that supports arrays. On many systems,
sh
isdash
which does not support arrays. So, usebash script
when executing this script.