Linux: Traverse Directory: find, xargs

By Xah Lee. Date: . Last updated: .

How to list only files who's name matches a text pattern?

# list files ending in .html
find . -name "*.html"

How to 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

How to delete all files who's name matches a text pattern?

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

be very careful with this. Usually, you should first do find . -name "*~".

A much faster way is to use the -delete option of find directly.

# delete all files whose name ends with ~.
find . -name "*~" -delete
# -delete is a option of find

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.

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.

How to delete empty files?

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

How to delete all empty dirs?

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

How to find recently modified file?

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

# list, file content modified in last 60 min
find . -mmin -60

# list, file accessed in last 60 min
find . -amin -60

Using “find” with “xargs”

How to 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:

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 Ole Tange for telling me about GNU Parallel. (Ole is the author)