Ubuntu: Counting files per owner recursively



Question:

From an entire directory structure I would like to output all the owners and how many files belong to each owner.

I would like an output like this:

+-------+-----+  | alex  |   3 |  | liza  | 345 |  | harry | 564 |  | sally |  23 |  +-------+-----+  

How can I do this in bash?


Solution:1

This won't draw the pretty lines but...

#!/bin/bash    for _user in `ls /home`  do      _count=`ls -R /home/$_user/ | wc -l`      echo "$_user = $_count"  done  


Solution:2

Consider using the Linux quota system. You'll have to enable it first and get it initialized, but it will require a lot less resources for creating a report.

  1. Install the quota package.
  2. Add the usrquota mount option to the file system in /etc/fstab.
  3. Remount or reboot the file system.
  4. Do the initial quota scan by running quotacheck -avug.
  5. Run repquota to list the usage. The File limits (used) column lists the amount of 'files' per user. However, it's not quite the same as the amount of actual files, but it's the number of inodes.

                            Block limits                File limits  User            used    soft    hard  grace    used  soft  hard  grace  ------------------------------------------------------  root      --   80088       0       0          12025     0     0         daemon    --       8       0       0              3     0     0         man       --     172       0       0             17     0     0         

To get a new report on a later time, it's only required to run repquota and this will run a lot quicker than running find all over again!

Note: it's not needed to set actual quota limits - just use it for reporting.


Solution:3

I would suggest to use find and wc in a for-loop:

users=`getent passwd | awk -F: '{print $1}'`  for user in $users  do      echo -n "file count for $user: "      find / -user $user -type f | wc -l  done  

Notes:

  • find is recursive by default.
  • You may want to prepend the find line with sudo in order to have the privileges for reading all directories. Or run the complete script as root.
  • It now limits to listings of files by the -type f filter. Remove that if you want to count directories too.
  • It's not terribly efficient, as it's first listing all names, while wc -l then just counts the number of newlines.

Parsing ls -R is inaccurate for several reasons. Firstly, it lists directory entries twice. Secondly, it leaves an additional blank line while it descends into directories. Thirdly, you'll need to pass -a to count hidden files. And finally, it won't be possible to filter directories.

See the demo below:

mkdir d1 d2 d3  touch a b c d1/a d2/a d3/a  tree  .  â"œâ"€â"€ a  â"œâ"€â"€ b  â"œâ"€â"€ c  â"œâ"€â"€ d1  â"‚   â""â"€â"€ a  â"œâ"€â"€ d2  â"‚   â""â"€â"€ a  â""â"€â"€ d3      â""â"€â"€ a    3 directories, 6 files    find . | wc -l  11    find . -type f | wc -l  7    ls -R | wc -l  16    ls -R | cat -   # to show why the number was 16  .:  a  b  c  d1  d2  d3    ./d1:  a    ./d2:  a    ./d3:  a  


Solution:4

Based on Ed Manet's answer, this will print the lines around the file counts:

#!/bin/bash    echo "+---------------+-------+"  for _user in `ls /home`  do      _count=`ls -R /home/$_user/ | wc -l`      printf "| $_user\t| $_count\t|\n"  done  echo "+---------------+-------+"  

Note that this works by counting the files in each user's home directory, so it can only scan the /home/ directory, and also it won't work correctly if one user has files in another user's directory.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »