Linux: Walk Dir. find, xargs

By Xah Lee. Date: . Last updated: .

List Files by File Name Pattern

# list files ending in .html
find . -name "*.html"
# list files ending in .html ignore letter case
find . -iname "*.html"

List Files by File Size Filter

# list files larger than 9 mibi bytes
find . -size +9M
# list files smaller than 9 kibi bytes
find . -size -9k
# list files exactly 1234 bytes
find . -size 1234c

Delete Files by File Name Pattern

# delete all files, name ends with ~
find . -name "*~" -delete

Be very careful when using -delete. Make sure you test first without -delete, and make sure -delete is the last argument. Otherwise you may delete everything.

Delete empty files

# list all empty files
find . -type f -empty
# delete all empty files
find . -type f -empty -print -delete

Delete empty dirs

# list empty dirs
find . -depth -empty -type d
# delete empty dirs
find . -depth -empty -type d -print -delete

Find Recently Modified File

By Modified Time

# list files that's been modified within past 2 days
find . -atime -2
# list files that's modified in last 60 min
find . -mmin -60

By Access Time

# list files that has been opened (accessed) in last 60 min
find . -amin -60

By Status Time

# list files whose file status changed in last 60 min
find . -cmin -60

Using -exec option

you can call a command with the -exec option.

When you use -exec, it spawn process to run the shell command for each file.

# delete all files whose name ends with ~
find . -name "*~" -exec rm {} \;

find with xargs

xargs is a command that is used together with find to allow you to call arbitrary unix commands on list of files.

use “find” on file names that may contain spaces or dash

# print file names that may contain spaces
find . -print0 | xargs -0 -l -i echo "{}";
-print0
use null char (ASCII 0) as file name separator. (by default -print uses newline character.)

Here's the options used for xargs:

-0
parse input using null char as seperators and take any special char in file name as literal.
-l
pass just one file name at a time.
-i
use {} as placeholder for file name.
"{}"
Quote around the entire file name, so that echo (or another program) will see it as one argument instead of several. (Note: the -i must come after -l)

Here's a useful example:

# convert all png in a dir to jpg
# file name should not contain ttt. if so, change ttt to hhh or something random

find . -name "*png" -print0 | xargs -0 -L1 -I ttt magick ttt ttt.jpg

Use GNU Parallel for xargs

Note: a modern replacement for xargs is GNU parallel. The syntax is almost indentical to xargs, except it runs in parallel. It also doesn't have problems with file names containing quotes or apostrophes.

Thanks to author of GNU Parallel, Ole Tange for telling me about it.

Linux, Files and Dirs