Skip to content

/commands/find/find-empty-files-directories

find . -empty: find and delete empty files and directories

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · find (GNU findutils) 4.11.0updated
tool
find
versions
GNU findutils 4.x, BSD find (macOS)
os
linux, macos, windows

find . -type f -empty lists files of size 0 and find . -type d -empty lists directories that contain nothing. Check the list first, then add -delete to remove them: find . -type d -empty -delete. -delete processes the deepest entries first, so a directory that becomes empty after its empty subdirectories are removed is deleted too. The starting directory itself is removed as well if it ends up empty; use -mindepth 1 to keep it.

Example

bash
mkdir -p data/a/b/c data/keep data/logs
touch data/empty.txt data/logs/today.log data/keep/.gitkeep
printf 'x\n' > data/notes.txt
echo "empty files:"
find data -type f -empty | sort
echo "empty directories:"
find data -type d -empty | sort
find data -mindepth 1 -type d -empty -delete
echo "left after -delete:"
find data | sort

Output

empty files:
data/empty.txt
data/keep/.gitkeep
data/logs/today.log
empty directories:
data/a/b/c
left after -delete:
data
data/empty.txt
data/keep
data/keep/.gitkeep
data/logs
data/logs/today.log
data/notes.txt

Before deleting, only data/a/b/c is an empty directory: a and b each contain one directory. -delete removed c, then b and a as each became empty. data/keep survived because of its .gitkeep, and data/logs because it contains a file, even an empty one.

Variants

CommandDoes
find . -type f -emptyList empty files
find . -type d -emptyList empty directories
find . -emptyBoth
find . -type f -empty -deleteDelete empty files
find . -mindepth 1 -type d -empty -deleteDelete empty directories, keep the starting directory
find . -type d -empty -not -path "./.git/*" -deleteSkip the .git directory
find . -depth -type d -empty -exec rmdir {} +Same result with rmdir, which refuses to remove anything not empty
find . -type f -empty | wc -lCount empty files

Safety

rmdir is a safe alternative for directories: it fails with Directory not empty instead of removing content, so a wrong pattern cannot delete files. Empty files are sometimes meaningful (lock files, __init__.py in Python packages, .gitkeep), so limit the search with -name or -path when cleaning a project.

Platform notes

GNU find (Linux, Git Bash) and BSD find (macOS) both support -empty, -delete, -mindepth and -depth. On a minimal find without -empty, -size 0 selects empty files. If find cannot delete an entry (no permission, or a file locked by another program on Windows), it prints an error for that entry, continues with the rest and exits with a non-zero status.

FAQ

Why does -delete not remove a directory that only contains empty directories?

It does with GNU and BSD find, because -delete implies -depth: the contents of a directory are processed before the directory itself, so the inner empty directories go first and the parent is empty by the time find reaches it. With -exec rmdir {} ; you must add -depth yourself.

Does -empty count a file that contains only a newline?

No. -empty is true only for files of size 0 and directories with no entries. A file with a single newline has size 1. Use -size -2c to include files of 0 or 1 byte, and check them before deleting.

How do I keep a placeholder like .gitkeep from being deleted?

A directory with a .gitkeep file is not empty, so -type d -empty skips it. If the .gitkeep files are empty themselves, exclude them from the file search with -not -name .gitkeep.

Sources