2

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?

2
  • I'm not sure this is the best approach to comparing two directories. Are you sure this is what you should be asking?
    – Daniel Beck
    Jul 24, 2013 at 7:28
  • 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. Jul 24, 2013 at 7:33

3 Answers 3

2

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.

3
  • 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? Jul 24, 2013 at 7:50
  • @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.
    – Daniel Beck
    Jul 24, 2013 at 7:56
  • 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. Jul 24, 2013 at 8:02
5
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
2

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)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .