Register
It is currently Fri Oct 31, 2014 5:59 am

Another directory/file script request . . .


All times are UTC - 6 hours


Post new topic Reply to topic  [ 7 posts ] 
Author Message
 PostPosted: Mon Dec 21, 2009 5:36 pm   

Joined: Mon Dec 21, 2009 4:57 pm
Posts: 4
Good Day All . . .

I am out of my depth and I have tried many scripts within my knowledge level but none work.

I have a storage device that stores my daily files as a directory under the filename YYYYMMDD.Mint5. Each day has its' own directory. There are at least 40 - 60 directories going back as least 1 1/2 months. I want to keep a limit of say 30 days so any directory older than 30 days is deleted. I'll put this in a file that is run once a day.

So far I have tried find /storage/* -mtime +30 -exec rm -Rdf {} \; and others .The problem is that it goes through the entire hard drive looking for older files. Luckily, I commented out the -exec part and stopped it after a few minutes.

I THINK what I am looking for is a loop script that isolates an old folder through a date variable then takes that filename into a rm -Rdf command and deletes that directory and begins the loop again.

Question 1: Is this script possible?
Question 2: If Yes then a sample would be very greatly appreciated.

My problem is that I create a new BASH script about once or twice a year so I forget more than I learn. My apologies.

Thanks.


Top
 Profile  
 PostPosted: Tue Dec 22, 2009 2:19 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
This is highly untested and might need some fine tuning when it comes to retrieving the date.
Code:
#!/bin/bash
path=$1
# Get the current epoch timestamp
epoch_old=$(date +%s)
# How many days back are we looking
days=$2
# Calculate the amount of seconds X days are and subtract it from the current date.
let epoch_old=epoch_old-\(86400*days\)
# Make sure we have the correct time styled output from ls(1)
OPT="--time-style=+%c -l"
# List all the files in $path
for i in $(ls $path $OPT); do
   # Chop out the creation timestamp
   time=$(echo $i | awk '{print $6" "$7" "$8" "$9" "$10" "$11}')
   # Filename
   file=$(echo $i | awk '{print $12}')
   # Figure out the epoch timestamp from the creation timestamp of the filename
   epoch_time=$(date --date "$time" +%s)
   # If the line above creates a number greater then what we created at the top of the file then the file is newer and vice versa
   if [ $epoch_time -lt $epoch_old ]; then
     # rm $file ...
     # Execute commands when the file is too old here.
     echo "File $file is older $days days"
   fi
done


Usage: ./script.sh /path/to/files <days>

Hope this atleast gives you a hint how you can do it :) and as i said, highly untested (I don't have a GNU ls or GNU date atm so can't really test it :P)

Best regards
Fredrik Eriksson


Top
 Profile  
 PostPosted: Tue Dec 22, 2009 11:11 am   

Joined: Mon Dec 21, 2009 4:57 pm
Posts: 4
fredrik.eriksson thanks for the quick reply and the sample.

I modified your script because the file location and file age are static.

Unfortunately the let epoch_old=epoch_old-\(86400*days\) line generated an error and the $file variable was never filled. The two are obviously related.

Do you see any problem with the line? I searched for the syntax for couldn't come up with anything.

Thanks


Top
 Profile  
 PostPosted: Wed Dec 23, 2009 7:29 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
the $file variable might not be 100% correct.. the output I used for sample came from a Solaris ls(1) which might output somewhat different then GNU ls(1) does.

What kind of error do you get from let epoch_old=epoch_old-\(86400*days\)?
Did you add the second argument when executing the scripts? the variable $days must contain a integer value.

an example would be:
./script.sh /storage/ 1

This would execute the script to check /storage/ for files older then 1 day

Best regards
Fredrik Eriksson


Top
 Profile  
 PostPosted: Thu Dec 24, 2009 4:21 pm   

Joined: Mon Dec 21, 2009 4:57 pm
Posts: 4
redrik.eriksson thanks again for the quick reply.

The error message for let epoch_old=epoch_old-\(86400*days\) is
"./delete_old.sh: 11: let: not found"
My research and knowledge puts that as a valid command (strange).

I modified the script to make the command line arguments static within the script since both will never change. The storage area and days to delete will always be the same. The error showed as first written also.

I have started experimenting with parts of the script to see where the variables fail. I will advise.

Again Thanks.


Top
 Profile  
 PostPosted: Sun Dec 27, 2009 11:21 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
Well the let part should work, but there could be some errors as how bash interprets it.

you can change the line to use the built-in version (i'm just stuck in the old ways of SH)
Code:
epoch_old=$(($epoch_old * (86400 * $days)))


If that doesn't work, use bc(1)
Code:
epoch_old=$(echo "$epoch_old * ( 86400 * $days )" | bc)


Best regards
Fredrik Eriksson


Top
 Profile  
 PostPosted: Sat Jan 23, 2010 2:16 pm   

Joined: Mon Dec 21, 2009 4:57 pm
Posts: 4
Hello

Thank You fredrik.eriksson for the replies. Sorry for the delay getting back. It was caused by frustration and I lost the address to get here (dumb!). But I'm back.

I solved the problem with a modification of your bash script. The script that you gave me was a problem. I think it was the 'time' variable. I couldn't get it working.

Your script did help me immeasurably. It solved the problem of why I could not get my original script to work. I was stuck at the line where something=$(date --date "25 days ago" +%y%m%d) or something like this.

My stored backups are folder titled yymmdd-Mint5 or yymmdd-partimage so I needed to loop a script to go back 45 days, 46 days, 47 days, etc. I could not get "45 days ago" into a loop. Your script gave me the answer. I could substitute a variable for '45 days ago'. I tried a lot of syntax on my own but nothing I tried worked.

Basically, my script looks like this:

#.............................................................#delete from 45 days ago plus 14 days back
for LAP in {45..58}
do
for file in /storage/*
do
if [ "${file%%.*}" == "/storage/"$(date --date $LAP" days ago" +%y%m%d)*Mint5 ]
then
rm -Rdf "/storage/"$(date --date $LAP" days ago" +%y%m%d)*Mint5
fi
if [ "${file%%.*}" == "/storage/"$(date --date $LAP" days ago" +%y%m%d)*partimage ]
then
rm -Rdf "/storage/"$(date --date $LAP" days ago" +%y%m%d)*partimage
fi
done
done

I removed all the comments. Hope I didn't remove too much. Scripting is not my strong point.

It may not look pretty but it works. I run it as a cron job and so far (one month) it took out all the Mint5 and partimage backups older than 44 days plus 14 days for good measure on every day.

I want to Thank You for your help. I appreciated it.


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Yahoo [Bot] and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP