0

I want to list the number of directories under each subdirectory tree of the present directory. As there are too many directories, I can't go into individual directories and check. I would like to produce a report something like the one shown in the following picture:

enter image description here

The issue is: my server is giving some warning that the maximum limit of creating directories is reached. So I wanted to know which directory in my parent directory has the maximum sub-directories (excluding files),

  • A small change: where in the pic it says -dir1 -- 8000 (total count of only dirs including all sub directories,no files).. – MostWanted Jul 17 '15 at 13:01
  • possible duplicate of Where are my inodes going? – Gilles Jul 17 '15 at 23:10
  • Are you concerned about reaching the inode limit, the path length, or something else? – roaima Jul 17 '15 at 23:49
  • All these answers, not even a single explanation of what is doing what. Magic is magic indeed. – user123418 Jul 18 '15 at 1:51
  • I am getting an error in /var/adm/messages "vxfs: [ID 702911 kern.warning] WARNING: msgcnt 5555 mesg 128: V-2-128: number of links reached vx_maxlink for inode 53685 on filesystem". And on searching about it i found out that it is due to the number of sub-directories in FS reaching a limit 32k. – MostWanted Jul 21 '15 at 15:30
1

You could find the toplevel directories first, then use a second find, to count the number of files and directories within the toplevel directory:

$ for dir in $(find . -maxdepth 1 ! -path . -type d | sort); \
      do echo -n "$dir " && find $dir ! -path . | wc -l ; done
./adir 1151
./anotherdir 140
./623de41e44 280
./examples 154
...
1

Will something like this suit your need:

The path /boot is used for sample demonstration. Change it to the directory you need.

for DIR in $(find /boot/* -maxdepth 1 -type d)
do
    printf "%40s: %10d\n" "${DIR}" $(find ${DIR}|wc -l)
done

Output:

                          /boot/grub:        282
                    /boot/grub/fonts:          2
                  /boot/grub/i386-pc:        272
                   /boot/grub/locale:          4
                    /boot/lost+found:          1
1

Pure ksh93 solution:

FIGNORE='@(.|..)'
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

Result from /usr/src:

linux-3.17.7-gentoo/:   561
linux-3.5.7-gentoo/:    517
linux-3.7.10-gentoo/:   505
linux-3.7.9-gentoo/:    513
linux-3.8.13-gentoo/:   551
linux-4.0.5-gentoo/:    1849
  • this commands seems to be giving total number of files + directories. can you modify it just to give directories(and all the sub-directories under it) – MostWanted Jul 21 '15 at 15:45
  • @MostWanted Just remove double dots glob: for dir in */; do a=( "$dir"/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done – jimmij Jul 21 '15 at 17:56
  • This command didn't give me the right output. Might be it was not checking under all the levels of the sub-directories. I have explained the question with an example image. Can you please check and provide the new command. – MostWanted Jul 29 '15 at 21:57
  • @MostWanted Which shell are you using? This command gives me right answer on bash and zsh. I don't have ksh at hand to check. The glob **/* descent into all subdirectories recursively so will give you total number of files and directories. You may need to set some option to make ** work, as setopt -s globstar in bash. – jimmij Jul 29 '15 at 23:12
  • my server uses bash.. – MostWanted Jul 30 '15 at 18:27
0

try

  find * -print | awk -F/ '{c[$1]++;} END { for (c2 in c) printf "-%s -- %d\n",c2,c[c2] ;} '

where

  • find from directory above the ones you want to sum up
  • awk will count top level dir and file and sum up at the end.
0

The following little loop will list a count of all files (excepting symlinks) in child directories of . which exist on the same filesystem as the child directory.

for d in ./* ./.[!.]* ./..?*
do  ! [ -h "$d" ]  &&
      cd "$d" 2>&3 || continue
      printf "%s:\t" "$d"
      find .//. -xdev -depth ! -type l |
      grep -c '^\.//\.'
      cd ..
done  3>/dev/null

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.