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 formatyyyy_mm_dd
.timestamp
is re-arranged asyyyy_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 usingdate %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