简体   繁体   中英

counting files, directories and subdirectories in a given path

I am trying to figure how to run a simple script "count.sh" that is called together with a path, eg:

count.sh /home/users/documents/myScripts

The script will need to iterate over the directories in this path and print how many files and folders (including hidden) in each level of this path.

For example:

  1. 7
  2. 8
  3. 9
  4. 10

(myScripts - 7, documents - 8, users -9, home - 10)

And by the way, can I run this script using count.sh pwd ?

More or less something like that:

#!/bin/sh

P="$1"

while [ "/" != "$P" ]; do
    echo "$P `find \"$P\" -maxdepth 1 -type f | wc -l`"
    P=`dirname "$P"`;
done
echo "$P `find \"$P\" -maxdepth 1 -type f | wc -l`"

You can use it from the current directory with script.sh `pwd`

You could try the following

#!/bin/bash

DIR=$(cd "$1" ; pwd)
PREFIX=
until [ "$DIR" = / ] ; do 
    echo -n "$PREFIX"$(basename "$DIR")" "$(ls -Ab "$DIR" | wc -l)
    DIR=$(dirname "$DIR")
    PREFIX=", "
done
echo

( ls -Ab lists all files and folders except . and .. and escapes special characters so that only one line is printed per file even if filenames include newline characters. wc -l counts lines.)

You can invoke the script using

count.sh `pwd`

Another approach is to handle separation or tokenizing the path using an array and controlling word-splitting with the internal field separator ( IFS ). You can include the root directory if desired (you would need to trim the additional leading '/' in the printout in that case)

#!/bin/bash

[ -z "$1" -o ! -d "$1" ] && {
    printf "error: directory argument required.\n"
    exit 1
}

p="$1"  ## remove two lines to include /
[ "${p:0:1}" = "/" ] && p="${p:1}" 

oifs="$IFS"     ## save internal field separator value
IFS=$'/'        ## set to break on '/'
array=( $p )    ## tokenize given path into array
IFS="$oifs"     ## restore original IFS

## print out path level info using wc
for ((i=0; i<${#array[@]}; i++)); do
    dirnm="${dirnm}/${array[i]}"
    printf "%d. %s -- %d\n" "$((i+1))" "$dirnm" $(($(ls -Al "$dirnm" | wc -l)-1))
done

Example Output

$ bash filedircount.sh /home/david/tmp
1. /home -- 5
2. /home/david -- 132
3. /home/david/tmp -- 113

As an alternative, you could use a for loop to loop through and count the items in the directory at each level instead of using wc if desired.

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