(Ab)using Bash Loops to Rename Log Files by Date Automatically

(Ab)using Bash Loops to Rename Log Files by Date Automatically

(Ab)using Bash Loops to Rename Log Files by Date Automatically

 

Log files are the bread and butter of system and application diagnostics — but without proper naming conventions, managing hundreds or thousands of these files can become a nightmare. If you’ve ever wrestled with a mess of error.log, access.log, and service.log that were just randomly overwritten each day, this post is for you.

We’re going to leverage the power of Bash loops (sometimes a bit too cleverly) to automate daily log renaming using standardized, date-stamped filenames. Not only will this make your logs easier to archive, but it’ll also prevent accidental overwrites and improve visibility into your server’s past health.

1. Why Rename Logs Automatically?

Let’s start with the “why”. Imagine your service produces a new application.log each day. When a cron job restarts your app nightly or logs rotate by default, you often lose yesterday’s data unless you backup or rename it manually. Automating renaming ensures persistence and order.

We’d rather see a structure like this:

application-2024-04-01.log
application-2024-04-02.log
application-2024-04-03.log

This way, you gain immediate clarity on log history, enabling better monitoring and easier debugging when something goes wrong. And Bash is the perfect tool to get this done.

2. Bash Setup: Basics of Looping Through Log Files

Let’s build our Bash loop. The first thing we need is a way to iterate through the logs. A simple for loop will do:

#!/bin/bash

LOG_DIR="/var/log/myapp"
cd "$LOG_DIR" || exit 1

for file in *.log; do
    echo "Processing $file"
done

Here’s what’s happening:

  • We set LOG_DIR for reusability and safety.
  • cd ensures we’re operating in the correct directory.
  • The for loop scans all files ending in .log.

Let’s now work on how to timestamp them properly.

3. Renaming Files with Timestamps

To add a timestamp like -2024-06-01, we can capture the current date using the date command:

#!/bin/bash

LOG_DIR="/var/log/myapp"
cd "$LOG_DIR" || exit 1

date_suffix=$(date +%F)

for file in *.log; do
    base=$(basename "$file" .log)
    mv "$file" "${base}-${date_suffix}.log"
    echo "Renamed $file to ${base}-${date_suffix}.log"
done

Explanation:

  • date +%F outputs the current date in YYYY-MM-DD format.
  • basename strips .log from the filename.
  • mv renames the file by appending the date.

This script can be placed in /usr/local/bin/rename-logs.sh and set up in a cron job for nightly execution. No more overwrites!

4. Making It Smarter: Skip Already-Renamed Files

A wrinkle: what if the script gets run twice in one day? You could end up renaming a file like app-2024-06-01-2024-06-01.log. Let’s only rename files that haven’t already been date-stamped.

#!/bin/bash

LOG_DIR="/var/log/myapp"
cd "$LOG_DIR" || exit 1

date_suffix=$(date +%F)

for file in *.log; do
    if [[ "$file" == *"$date_suffix"* ]]; then
        echo "Skipping $file (already dated)"
        continue
    fi

    base=$(basename "$file" .log)
    new_name="${base}-${date_suffix}.log"

    if [[ -e "$new_name" ]]; then
        echo "Warning: $new_name already exists. Skipping."
        continue
    fi

    mv "$file" "$new_name"
    echo "Renamed $file to $new_name"
done

Here, the script checks if the filename already contains today’s date or if the target name already exists, skipping it in either case. This is important for idempotency and safety when scripts run via cron.

5. Pro Tips and Considerations

  • Use logrotate in conjunction with this approach if your logs are large. Rotate first, then rename.
  • Parameterize the script to accept a directory or file format as arguments for flexibility:
  • #!/bin/bash
    
    LOG_DIR="$1"
    DATE_SUFFIX=${2:-$(date +%F)}
  • Handle compressed logs like *.log.gz with extended patterns or loops.
  • Logging your script activity (e.g. to /var/log/log_renamer.log) can help audit and debug automation failures.
  • Timeouts and heavy directories: On large systems, avoid tight loops over thousands of files. Consider adding sleeps or using find -maxdepth to control scope.

Conclusion

While it’s tempting to think Bash is only for simple shell tasks, it can be surprisingly powerful for automation when used creatively — possibly abuse-level creative. By combining Bash loops with simple file pattern matching and date formatting, you can unlock robust log organization on any server with zero dependencies.

Want to go further? Add archiving (e.g. tar + gzip) to compress old logs after renaming them. Happy scripting!

 

Useful links: