简体   繁体   中英

How can I recursively count the number of each type of file in a unix directory without using find or -type?

I am attempting to count the number of regular files, subdirectories, symbolic links, block special files, and character special files that are contained in a directory in unix, but each time I try I get inconsistent results. I consistently get results for normal files, but never the same number, and none of the others stay the same either. I have attached the script I am trying to use right now. The proper usage for the script can be seen in the error message that checks for the correct input.

userinput=$1
#makes sure that there is only one input
if [ $# -ne 1 ];
then
        echo "Usage: dircount.sh directory" 1>&2
        exit 0
fi
#makes sure the file is a readable directory
if [ ! -d "$userinput" ] || [ ! -r "$userinput" ];
then
        echo "Please enter a directory you can read" 1>&2
        exit 0
else
        #prints the current directory
        cd $userinput
        pwd
        regfiles=0
        numsubs=0
        numsymb=0
        numblock=0
        numspecial=0
        for file in `ls -l $*`
        do
                if [ -f "$file" ];
                then
                        regfiles=`expr 1 + $regfiles`
                fi
                if [ -d "$file" ];
                then
                        numsubs=`expr 1 + $numsubs`
                fi
                if [ -L "$file" ];
                then
                        numsymb=`expr 1 + $numsymb`
                fi
                if [ -b "$file" ];
                then
                        numblock=`expr 1 + $numblock`
                fi
                if [ -c "$file" ];
                then
                        numspecial=`expr 1 + $numspecial`
                fi
        done

Don't parse ls . Use bash's recursive globbing

shopt -s globstar nullglob
for file in **; do ...

I would use an associative array to hold the counts

declare -A num
for file in **; do 
    [[ -f $file ]] && (( num["reg"]++ ))

Something like the next can work (need bash4).

declare -A SUMTYPES
while read -r type
do
    let SUMTYPES["$type"]++
done < <(stat -c "%F" *)   #this is for gnu version of "stat"

for i in "${!SUMTYPES[@]}"
do
    echo "${SUMTYPES[$i]}   $i"
done

produces for example the next output

1   regular empty file
5   directory
1   symbolic link
9   regular file
1   fifo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM