Process for Building a Find Command

While I was setting up logrotate on a server, I needed to traverse a large user directory to find all of the log files, ideally sorted by their size, excluding the mail directory.

This is what I came up with:

$ find ~/ -not \( -path ~/mail -prune \) -type f -name '*[._]log' -exec du -ah {} + | sort -h

Building Up the Command

I started by doing a simple find, without knowing exactly what I was getting myself into:

$ find ~/ -type f -name '*[._]log'

You can read this in simple English as saying “Find in the home directory, any files with a name ending in either ‘.log’ or ‘_log’”. This was a good start, but I had way too many hits and the actual search was taking a couple of seconds to complete — way too long! 😛

Curious about performant ways of excluding directories while using find, I found this answer on Stackoverflow.

Using the above answer as guidance, I pruned the massive amount of email folders that find was traversing:

$ find ~/ -not \( -path ~/mail -prune \) -type f -name '*[._]log'

At this point, it is a simple matter of executing du to get the file size of each log, and then piping the output to sort the results:

$ find ~/-not \( -path ~/mail -prune \) -type f -name '*[._]log' -exec du -ah {} + | sort -h