Reputation: 2275
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?
Upvotes: 1
Views: 941
Reputation: 113814
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:
shopt -s nullglob
dirs=(*/)
ndir="${#dirs[@]}"
files=(*)
nfile=$(( "${#files[@]}" - ndir))
echo "files=$nfile, directories=$ndir"
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 of files
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
is dash
which does not support arrays. So, use bash script
when executing this script.
Upvotes: 1
Reputation: 753525
Use a wild card: for file in *; do …; done
. That keeps the spaces in the names correct. Consider shopt -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:
#!/bin/bash
shopt -s nullglob
files=0
dir=0
for file in *
do
if [ -d "$file" ]
then
dir=$(($dir+1))
else
files=$(($files+1))
fi
done
echo "files=$files, directories=$dir"
In Bash, there are also other ways of writing the arithmetic, such as ((files++))
.
Upvotes: 1