Home > Enterprise >  Delete the log files have 30 days old timestamp in log filename in shell script
Delete the log files have 30 days old timestamp in log filename in shell script

Time:12-12

I have a below log files who have date mention in filename. I want to delete the files have 30 days old date in filename. someone please provide the solution.

log files:-

fortinetPerformanceMet_01_11_2022.log
fortinetTokenGeneration_05_11_2022.log
fortinetTopDestination_10_12_2022.log
fortinetTopSource_11_12_2022.log

I want to delete a logfiles who have 30 days old date in filename. after deleting 30 days old files the expected output from above file will be

fortinetTopDestination_10_12_2022.log
fortinetTopSource_11_12_2022.log

I tried below

find /path/to/files/ -type f -name "*_*_*_$2022.log" -mtime 30 -delete, but it will delete the files according to the file timestamp.

CodePudding user response:

Assuming:

  • Your date command supports -d option.
  • The timestamp in the filenames represents dd_mm_yyyy.

Then would you please try:

#!/bin/bash

oldday=$(LC_TIME=C date -d "-30 days" " %Y_%m_%d")
while IFS= read -r f; do
    if [[ $f =~ _([0-9]{2})_([0-9]{2})_([0-9]{4})\.log ]]; then
        timestamp="${BASH_REMATCH[3]}_${BASH_REMATCH[2]}_${BASH_REMATCH[1]}"
        if [[ $oldday > $timestamp ]]; then
            echo rm -- "$f"
        fi
    fi
done < <(find /path/to/files/ -type f -name "*_*_*_*.log")
  • oldday is assigned to the date 30 days ago in the format yyyy_mm_dd.
  • timestamp is re-arranged as yyyy_mm_dd.
  • Now we can compare them with the > operator.

If the output looks good, drop echo.

CodePudding user response:

If I understand the timestamp is given in the filename only.

  • We can use regex to extract the dd_mm_yyyy components from the filename
  • We can rearrange this to yyyymmdd format
  • Then we can use yyyymmdd to convert that to a second relative to an epoch date in seconds using date %s
  • We can also get today's date relative to the same epoch date in seconds using date %s
  • Then we can simply subtract the two dates and change the units from seconds to days
  • If the days is less than 30 we don't delete

Here's the code:

now=$(date  %s)
for f in $(find . -type f -name "*_*_*.log")
do
    if [[ $f =~ _([0-9]{2})_([0-9]{2})_([0-9]{4})\.log ]]; then
        yyyymmdd=${BASH_REMATCH[3]}${BASH_REMATCH[2]}${BASH_REMATCH[1]}
        old=$(date  %s -d $yyyymmdd)
        ((age = (now -old) / 60 / 60 / 24))
        echo "file: $f age: $age"
        if (( age < 30 )); then continue; fi
        echo delete $f
        # rm $f # UNCOMMENT WHEN YOU'RE HAPPY
    fi
done

For your sample data, the above script outputs:

file: ./fortinetPerformanceMet_01_11_2022.log age: 41
delete ./fortinetPerformanceMet_01_11_2022.log
file: ./fortinetTopDestination_10_12_2022.log age: 2
file: ./fortinetTopSource_11_12_2022.log age: 1
file: ./fortinetTokenGeneration_05_11_2022.log age: 37
delete ./fortinetTokenGeneration_05_11_2022.log
  • Related