/commands/find/find-files-older-than-days
find -mtime +7: find and delete files older than N days
- tool
- find
- versions
- GNU findutils 4.x
- os
- linux, macos, windows
find /path -type f -mtime +7 lists files whose content was last modified more than 7 days ago; add -delete to remove them. Run it once without -delete to check the list. -mtime counts in whole 24-hour periods and the fractional part is discarded, so +7 means "at least 8 full days old", not "older than 7 days" in the everyday sense.
Example
mkdir -p logs
touch -d '2 days ago' logs/recent.log
touch -d '10 days ago' logs/old.log
touch -d '30 days ago' logs/older.log
find logs -type f -name '*.log' -mtime +7 | sortOutput
logs/old.log logs/older.log
Delete them
mkdir -p logs
touch -d '2 days ago' logs/recent.log
touch -d '10 days ago' logs/old.log
find logs -type f -name '*.log' -mtime +7 -print -delete
ls logsOutput
logs/old.log recent.log
Put -delete last: find evaluates the expression from left to right, so find logs -delete -name '*.log' would delete everything before testing the name.
How the numbers work
| Test | Matches |
|---|---|
| -mtime +7 | Modified at least 8 days ago (age in days, rounded down, is greater than 7) |
| -mtime 7 | Age rounded down is exactly 7 days |
| -mtime -7 | Modified less than 7 days ago |
| -mmin +60 | Modified more than 60 minutes ago |
| -atime / -ctime | Same arithmetic for access time and status-change time |
| -newermt "2026-01-01" | Modified after a given date (GNU find) |
Alternatives to -delete
# portable (POSIX) form
find logs -type f -mtime +7 -exec rm -f {} +
# compress instead of deleting
find logs -type f -name '*.log' -mtime +7 -exec gzip {} +The + at the end passes many files to a single rm or gzip call, which is much faster than \; (one process per file).
Minutes, dates and depth
-mmin works in minutes, -newermt compares with a date or a relative time that GNU find parses like touch -d, and -maxdepth 1 stops find from descending into subdirectories:
mkdir -p logs/sub
touch -d '10 days ago' logs/old.log logs/sub/deep.log
touch -d '90 minutes ago' logs/hour.log
touch logs/new.log
echo '--- older than 60 minutes:'; find logs -type f -mmin +60 | sort
echo '--- not newer than 5 days ago:'; find logs -type f ! -newermt '5 days ago' | sort
echo '--- top level only:'; find logs -maxdepth 1 -type f -mtime +7Output
--- older than 60 minutes: logs/hour.log logs/old.log logs/sub/deep.log --- not newer than 5 days ago: logs/old.log logs/sub/deep.log --- top level only: logs/old.log
Common mistakes
- Unquoted globs.
find . -name *.log -mtime +7lets the shell expand*.logfirst; with several matching files in the current directory find stops with paths must precede expression. Always quote the pattern. - A missing terminator.
-exec rm {}without\;or+fails with missing argument to -exec. - Forgetting -type f. Without it,
-mtime +7 -deletealso matches old directories; find deletes an old directory only if it is empty, and prints an error for the others. - Changing the time you test.
-mtimeis the content modification time. Copying files without preserving times (cpwithout-p) resets it, so a restored backup looks new.
macOS and BSD find
BSD find on macOS supports -mtime, -mmin, -delete and -maxdepth with the same meaning, and also accepts units such as -mtime +7d or -mtime +12h. -newermt is supported there too, but touch -d '10 days ago' used in the examples is GNU-only; on macOS set a time with touch -t YYYYMMDDhhmm file. To find files by size instead of age, see find files larger than a size.
FAQ
Why does find -mtime +1 not match a file modified yesterday?
find rounds the age down to whole days, so a file 36 hours old has an age of 1 and +1 needs an age of at least 2. Use -mtime +0 for older than 24 hours, or -mmin +1440 for an exact minute count.
How do I delete old files but not the ones in subdirectories?
Add -maxdepth 1 right after the path, for example find logs -maxdepth 1 -type f -mtime +7 -delete. -maxdepth is a GNU and BSD extension; it must come before tests to avoid a warning.
How do I run this cleanup every day?
Put the command in a cron job or a systemd timer with an absolute path, and log its -print output. Test it once by hand without -delete, since cron runs it without asking.