Linux: Walk Dir: find, xargs

By Xah Lee. Date: . Last updated: .

List files whose name matches a text pattern

# list files ending in .html
find . -name "*.html"
# list files ending in .html ignore letter case
find . -iname "*.html"
linux shell find command 85396
The find command for traverse directory.

List only files larger than n bytes

# 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

[see Kilo vs Kibi, Mega vs Mibi]

Delete all files, name matches a text 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 -delete

Delete empty dirs

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

Find Recently Modified File

by day:

# list files whose content have been modified within past 2 days
find . -atime -2

By minute:

# list files whose file content is modified in last 60 min
find . -mmin -60

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

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

Using -exec option

Here's another way, slower:

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

Using the -delete option is much faster because it doesn't spawn processes. When you use -exec, it actually spawn process to run the shell command for each file.

The advantage of using -exec is that you can call any unix command, not just options supported by find.

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 "{}";

Here's the options used for xargs:

-print0
use null char (ASCII 0) as file name separator. (by default -print uses newline character.)
-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 bmp files to png in a dir. Requires “convert” from ImageMagick
find . -name "*bmp" -print0 | xargs -0 -l -i basename "{}" ".bmp" | xargs -0 -l -i convert "{}.bmp" "{}.png"

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