How to separately count number of files, directories, symbolic links and hard links within a single find run?

7,497

Solution 1

The following should do it. It requires GNU find; on OS X, install e.g. findutil using Homebrew.

find $directory -type d -printf d -o -type l -printf l -o -type f -links +1 -printf h -o -type f -printf f

This will print one character per encountered file system entry:

  • d if it's a file
  • l if it's a symbolic link
  • h if it's a file with hard links
  • f if it's a file (only if not h)

Output looks like this (actual excerpt on my system):

dfddfdfddfdfddfdfddfdfddfdfddfddfdfddfdffffffffddfdffdfffffffffddfdldfllfdlldffffdfllfdlllllldffffdffffldfllfddffdldfddddffffflllldllllldlffffldfllfdlldffffdfllfddffddfddddfffffldfddddfffffdfddddfffffdlllldffffldfffflflllldffflfdffflfdfllfddffffldffffdfffflldfffflllldffffdffffdfffflldfllfddffdldfddddfffffdllllddflfffflldfllfddffffdffffdffffldffffdffffdffffdffffllldffffldffffdffffldffffldffffdffffdffffllllllldffffldffffdfffflllllldfffflldffddldfllfdldfffflldfffflldffffdfffflldffffdffffdfllfdlldfffflllldfllfdlldffffdfllfdlllllldffffdffdldfllfdlldfffflldfffflldffffldffffldfffflldfllfdldffffldffffldffdldffdddffddffddffddldfllfdlldffffdffffdfffflldfffflldffffdffffllldffffdffffdfllfddffffldfffflllldffffldfffflllldffffdfllfddffdldddddfffdddddfffdddddfffdddddfffdldlfffflldlffffllldfffllldffffdlffffdlffffldfffflldffdldfllfdllldffffdffffdffffldfllfdlllldfffflldfllfdldfddffffffl

Redirect output to a file, and then it becomes simple string processing to count later.

Solution 2

find $directory -type d -exec echo dirs \; -o -type l -exec echo symlinks \; -o -type f -links +1 -exec echo hardlinks \; -o -type f -exec echo files \; | sort | uniq -c

Produces output like:

 326 dirs
2164 files
  40 hardlinks
 164 symlinks

Solution 3

Using the answer from Daniel Beck I developed the following solution which should work for most versions of find and also provides the counting magic:

output=$(find $directory -type d -exec printf d \; -o -type l -exec printf l \; -o -type f -links +1 -exec printf h \; -o -type f -exec printf f \;)
num_files=$(echo $output | grep -o "f" | wc -l)
num_directories=$(echo $output | grep -o "d" | wc -l)
num_symlinks=$(echo $output | grep -o "l" | wc -l)
num_hardlinks=$(echo $output | grep -o "h" | wc -l)
Share:
7,497

Related videos on Youtube

Florian Feldhaus
Author by

Florian Feldhaus

Updated on September 18, 2022

Comments

  • Florian Feldhaus
    Florian Feldhaus over 1 year

    To check a successfull migration I'm using find to count the number of files, directories, symbolic links and files with more than one hard link. As the directories to check contain a huge number of files, each find run takes several hours. Thus I search for a way to separately count number of files, directories, symbolic links and files with more than one hard link within a single find run.

    Here's what I currently do

    num_files=$(find $directory -type f | wc -l)
    num_directories=$(find $directory -type d | wc -l)
    num_symlinks=$(find $directory -type l | wc -l)
    num_hardlinks=$(find $directory -type f -links +1 | wc -l)
    

    How can I get those four counters within one find run?

    • HikeMike
      HikeMike almost 11 years
      I'm not sure this is the best approach to comparing two directories. Are you sure this is what you should be asking?
    • Florian Feldhaus
      Florian Feldhaus almost 11 years
      The best way to compare two directories is probably a dry run of rsync. But I need to proof that rsync copied all files, directories, symbolic links and hard links and I don't know a better way than doing it with find.
  • Florian Feldhaus
    Florian Feldhaus almost 11 years
    It worked fine on Mac OS X for me, but unfortunately I have to run the command on SunOS 5.10 where find doesn't support printf. Any suggestions how to achieve the same without printf?
  • HikeMike
    HikeMike almost 11 years
    @FlorianFeldhaus You're on an almost decade old Solaris? You should probably add that to your question. Other than to compile and install a better find... no idea. FWIW OS X find does not support -printf, you probably installed something better already.
  • Florian Feldhaus
    Florian Feldhaus almost 11 years
    Yes, I currently have to use it. The tools on it are not that old, but Solaris find does not support printf. I will try to get a Linux server where I have a recent GNU find.