How to separately count number of files, directories, symbolic links and hard links within a single find run?
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 noth
)
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)
Related videos on Youtube
Florian Feldhaus
Updated on September 18, 2022Comments
-
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, eachfind
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 singlefind
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 almost 11 yearsI'm not sure this is the best approach to comparing two directories. Are you sure this is what you should be asking?
-
Florian Feldhaus almost 11 yearsThe 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 withfind
.
-
-
Florian Feldhaus almost 11 yearsIt 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 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 Xfind
does not support-printf
, you probably installed something better already. -
Florian Feldhaus almost 11 yearsYes, I currently have to use it. The tools on it are not that old, but Solaris
find
does not supportprintf
. I will try to get a Linux server where I have a recent GNUfind
.