find files older than X days in bash and delete
Categories:
Efficiently Find and Delete Old Files in Bash

Learn how to use the find
command in Bash to locate and remove files older than a specified number of days, ensuring your systems stay clean and optimized.
Managing disk space is a crucial aspect of system administration and development. Over time, log files, temporary data, backups, and other generated content can accumulate, consuming valuable storage and potentially impacting system performance. The find
command in Bash is an incredibly powerful utility for navigating the file system and performing actions based on various criteria, including file age. This article will guide you through using find
to identify and safely delete files older than a specified duration.
Understanding the find
Command for Age-Based Searches
The find
command is versatile, but for age-based searches, we primarily focus on the -mtime
and -atime
options. These options allow you to specify a time duration relative to the file's last modification or access time, respectively. The number following these options represents the number of 24-hour periods.
-mtime +N
: Finds files whose data was last modified more than N 24-hour periods ago.-atime +N
: Finds files that were last accessed more than N 24-hour periods ago.
It's generally safer to use -mtime
for deletion tasks, as access times (-atime
) can be updated by simple read operations, which might not reflect the file's true 'staleness'. Modification time (-mtime
) is a more reliable indicator of when a file became 'old' or irrelevant.
find /path/to/directory -mtime +30 -print
Basic find
command to list files older than 30 days.
Safely Deleting Found Files
Before you delete any files, it's paramount to test your find
command to ensure it targets exactly what you intend. A common mistake is to immediately pipe find
's output to rm
without verification, which can lead to irreversible data loss. Always start by listing the files, then add the deletion action.
There are several ways to delete files found by find
:
- Using
-delete
(GNUfind
extension): This is the most efficient and often preferred method for GNUfind
as it avoids issues with large numbers of files or filenames containing special characters. - Using
-exec rm {} \;
: This method executesrm
for each found file. It's more portable across different Unix-like systems but can be slower for many files. - Using
-exec rm {} +
(GNUfind
extension): Similar toxargs
, this passes multiple filenames to a singlerm
command, making it more efficient than\;
for many files.
We will focus on the -delete
and -exec
methods for their robustness.
flowchart TD A[Start] --> B{"Define Target Directory & Age (N days)"} B --> C{"Construct `find` Command (e.g., -mtime +N)"} C --> D{Test Run: `find ... -print`} D --"Review Output"--> E{Output Correct?} E -- No --> C E -- Yes --> F{"Choose Deletion Method (-delete or -exec)"} F --> G{Execute Deletion Command} G --> H[End]
Workflow for safely finding and deleting old files.
find
command before adding any deletion action. A misplaced .
or /
could lead to unintended data loss. When in doubt, use -print
first!Practical Examples for Deletion
Let's look at some practical examples for deleting files and directories.
# 1. Find and delete files older than 60 days in a specific directory
# (using -delete for GNU find)
find /var/log/old_logs -type f -mtime +60 -delete
# 2. Find and delete empty directories older than 90 days
# (using -delete for GNU find)
find /tmp/backups -type d -empty -mtime +90 -delete
# 3. Find and delete files older than 30 days, excluding certain file types
# (using -exec rm {} \; for portability)
find /home/user/downloads -type f -mtime +30 \! -name "*.important" -exec rm {} \;
Examples of find
commands for various deletion scenarios.
find
twice: once for files, then once for directories. This ensures files are deleted before their parent directories become empty and are subsequently deleted.Automating Deletion with Cron Jobs
For routine cleanup, you can automate these commands using cron
jobs. A cron
job schedules commands to run at specified intervals.
To add a cron
job, open your crontab for editing:
crontab -e
Then, add a line specifying the schedule and the command. For example, to run a cleanup script every day at 2:00 AM:
0 2 * * * /path/to/your/cleanup_script.sh > /dev/null 2>&1
Ensure your cleanup script has execute permissions (chmod +x /path/to/your/cleanup_script.sh
). It's also good practice to log the output of cron jobs for auditing and debugging, rather than redirecting to /dev/null
.
# Example cleanup_script.sh
#!/bin/bash
LOG_FILE="/var/log/cleanup_$(date +%Y%m%d).log"
TARGET_DIR="/var/log/application"
DAYS_OLD="+90"
echo "Cleanup started at $(date)" >> "$LOG_FILE"
find "$TARGET_DIR" -type f -mtime "$DAYS_OLD" -print -delete >> "$LOG_FILE" 2>&1
find "$TARGET_DIR" -type d -empty -mtime "$DAYS_OLD" -print -delete >> "$LOG_FILE" 2>&1
echo "Cleanup finished at $(date)" >> "$LOG_FILE"
Example of a simple cleanup script to be used with cron.