LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-21-2008, 02:40 PM   #1
investmentbnker75
Member
 
Registered: Oct 2007
Location: Eastern Seaboard
Distribution: CentOS
Posts: 158

Rep: Reputation: 15
rm by date


Guys,

Im stumped on 1 last line of a script im writing, i need to have the script go into each directory called test* and rm anything older than 18 days from the day its executed. Cron will run it daily.

Heres what i have except what will determine the old than 18 days for removal. Sorry im a newb. Thanks!


#!/bin/bash

for i in test01 test02 test03 test04 test05 test06 test07 test08 test09 test10 test11 test12 ; do
rm -rf anything older than 30 days
done

Last edited by investmentbnker75; 08-21-2008 at 02:41 PM. Reason: different number of days
 
Old 08-21-2008, 02:57 PM   #2
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
Use find to identify files with an mtime older than 30 days and then feed the identified files to rm with xargs:
Code:
find . -name 'test*' -mtime +30 -type f -print0 |xargs -0 rm -f
 
Old 08-21-2008, 03:19 PM   #3
investmentbnker75
Member
 
Registered: Oct 2007
Location: Eastern Seaboard
Distribution: CentOS
Posts: 158

Original Poster
Rep: Reputation: 15
Thanks Matthew! So it should look like:

#!/bin/bash

for i in test01 test02 test03 test04 test05 test06 test07 test08 test09 test10 test11 test12 ; do
find . -name 'file*' -mtime +10 -type f -print0 | xargs -0 rm -rf
done

File equals:

file_backup_backup14_20080106.tgz
file_backup_backup14_20080107.tgz
etc...
 
Old 08-21-2008, 03:55 PM   #4
raconteur
Member
 
Registered: Dec 2007
Location: Slightly left of center
Distribution: slackware
Posts: 276
Blog Entries: 2

Rep: Reputation: 44
You don't really need xargs or the for loop (and the -type parameter, while probably good practice, isn't strictly necessary either if you are sure these files are all regular files)...

Code:
find . -name "file_backup*" -print -type f -mtime +10 -exec rm -f {} \;

Last edited by raconteur; 08-21-2008 at 04:01 PM.
 
Old 08-21-2008, 04:40 PM   #5
bos.beemer
LQ Newbie
 
Registered: Jul 2008
Posts: 1

Rep: Reputation: 0
I think the xargs approach is faster because it supplies all the arguments to rm that applies to all the files at once. However using -exec will supply the arguments one at a time and thus a bit slow. Besides I don't think you need -print0 either.

find . -name 'test*' -mtime +30 -type f |xargs -0 rm -f
 
Old 08-21-2008, 05:22 PM   #6
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
With the xargs method, you don't need to use the "for i in ... do ... done", just the single line I provided should do it. The only thing you might have to watch for is that find will recurse into sub-directories, and that the pattern passed to -name is specific enough to only get the files you want.

As a test to see if it is going to operate on the right files, do this first:
Code:
find . -name 'test*' -mtime +30 -type f -print0 |xargs -0 ls -l
If that lists only the files you want to delete, replace the "ls -l" with "rm -f".
 
Old 08-22-2008, 12:29 PM   #7
investmentbnker75
Member
 
Registered: Oct 2007
Location: Eastern Seaboard
Distribution: CentOS
Posts: 158

Original Poster
Rep: Reputation: 15
Thanks again Matthew, I wanted to try a variation of this, if it is possible. I would like to take files for the past two months and have a script that will keep the past two weeks and then every Sunday only. Is that possible?
 
Old 08-22-2008, 12:40 PM   #8
kenoshi
Member
 
Registered: Sep 2007
Location: SF Bay Area, CA
Distribution: CentOS, SLES 10+, RHEL 3+, Debian Sarge
Posts: 159

Rep: Reputation: 32
I thought using xargs is faster due to the fact that using -exec will fork a child of find for every argument, whereas xargs simply passes the argument to the resulting command?
 
Old 08-22-2008, 02:17 PM   #9
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
Quote:
Originally Posted by investmentbnker75 View Post
Thanks again Matthew, I wanted to try a variation of this, if it is possible. I would like to take files for the past two months and have a script that will keep the past two weeks and then every Sunday only. Is that possible?
Not with the -mtime option to find. If you want such complex behavior, you will probably want to write a perl script or something like that.

*edit* actually you might be able to do it with the printf option, and the -mtime option, ORed together with -o.

Last edited by matthewg42; 08-22-2008 at 02:19 PM.
 
Old 08-22-2008, 03:11 PM   #10
raconteur
Member
 
Registered: Dec 2007
Location: Slightly left of center
Distribution: slackware
Posts: 276
Blog Entries: 2

Rep: Reputation: 44
Actually this would be pretty simple to do in the shell if you're using GNU versions of 'ls'.

Code:
ls -l --time-style=+%a
will display the weekday of the modification time on the files.

There are other formats for the style (man ls for specifics, and man date for the formats)

Using that info and the find commands listed above you can construct a simple shell script to do what you want.
 
Old 08-22-2008, 03:29 PM   #11
investmentbnker75
Member
 
Registered: Oct 2007
Location: Eastern Seaboard
Distribution: CentOS
Posts: 158

Original Poster
Rep: Reputation: 15
Matthew/Raconteur,

Thanks for the response, but i am confused what the line in the script would be to remove all files but for the last 2 weeks and every Sunday for a two month period. Could you post an example? Thanks a million for the time and the help!
 
Old 08-22-2008, 05:11 PM   #12
raconteur
Member
 
Registered: Dec 2007
Location: Slightly left of center
Distribution: slackware
Posts: 276
Blog Entries: 2

Rep: Reputation: 44
This is quick and dirty, and only cursorily tested, the usual caveats apply. If I were writing this for keepsies I'd probably do a few things differently.

Change the initial file pattern to match whatever your files are named. I called it filter.sh but of course you can name it whatever you wish...

Remove the sharps if you want a very verbose version.

Code:
#!/bin/bash

for file in `find . -name "backup*" -print`; do
# echo "filter is examining $file"
  older_than_two_months=`find . -wholename $file -mtime +60 -print`
  if [ -n "$older_than_two_months" ]; then
#   echo "filter found that $file is older than two months, deleting"
    rm -f $file
  else
    older_than_two_weeks=`find . -wholename $file -mtime +14 -print`
    if [ -n "$older_than_two_weeks" ]; then
#     echo "filter found that $file is older than two weeks"
      sunday=`ls -l --time-style=+%a $file | awk '{print $6}'`
      if [ "$sunday" != "Sun" ]; then
#       echo "filter found that $file was not modified on a Sunday, deleting"
        rm -f $file
#     else
#       echo "filter found that $file was modified on Sunday, ignoring"
      fi
#   else
#     echo "filter found that $file is newer than two weeks"
    fi
  fi
done
hth

Last edited by raconteur; 08-22-2008 at 05:15 PM.
 
Old 08-22-2008, 05:46 PM   #13
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
Do you want to descend into sub-directories, or just remove files from one directory?
 
Old 08-22-2008, 05:54 PM   #14
raconteur
Member
 
Registered: Dec 2007
Location: Slightly left of center
Distribution: slackware
Posts: 276
Blog Entries: 2

Rep: Reputation: 44
Quote:
Originally Posted by matthewg42 View Post
Do you want to descend into sub-directories, or just remove files from one directory?
Good point, my stab at this assumes one directory.
However, I think if you added a -type f parameter to the initial find it would pass the multi-level test.
 
Old 08-22-2008, 06:15 PM   #15
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 63
OK, if you want to descend into sub-directories as well as working in the current directory, here's the command for you:
Code:
find . -type f -mtime +14 -printf "%Cw %p\n" | grep -v ^0 | cut -c3- | xargs rm -f
Please backup before doing this - I take no responsibility if it deletes the wrong files because I might have mis-interpreted your needs or made a mistake.

It is probably a good idea to run it without the "| xargs rm -f" on the end first and verifiy that the files it lists are indeed the ones you want to delete, and only the ones you want to delete. i.e.
Code:
find . -type f -mtime +14 -printf "%Cw %p\n" | grep -v ^0 | cut -c3-
OK, now for an explanation.

The -printf option to find can be used to print more information that the default (which is just to print the file path & name. In this case I used the format string "%Cw %p\n". Please look at the find manual page and find %C. If you read this section of the page, you should be able to see that "%Cw" means the day of week number (0-6) the file was last modified. (0 is Sunday). I could also have used %Ca which would print the day of week like "Sun", "Mon" and so on, but this is locale dependent, so it would not work on a machine with German language settings for example.

The next bit, "%p\n" just means the file path & name with a new line character after it.

The "-mtime +14" means to print only files older than 14 days since the last modification.

The "-type f" means to only print files.

The "." as the first option to find means "start in the current directory".

In you run the find command without the following pipeline, you will see something like this:

Code:
0 ./file1
3 ./file2
6 ./bob/file3
The number is the weekday of modification of the file (0=Sun, 3=Wed, 6=Sat), then the file name in question.

We do not want to delete files which were modified on a Sunday, so we exclude the lines beginning with 0 with the next part of the pipeline:
Code:
grep -v ^0
If the example output of the find command above is what you get, after the grep part, it will look like
Code:
3 ./file2
6 ./bob/file3
The next part of the pipeline:
Code:
cut -c3-
...prints only characters from column 3 onwards - it cuts off the day of week and the space. We now have just a list of files which we want to remove:
Code:
3 ./file2
6 ./bob/file3
This is the input to xargs which calls the specified command (rm -f) for groups of strings read from standard input - i.e. remove the listed files.

I hope that is clear. If you have further questions about it, feel free to ask.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
shell script to find modified date and last accessed date of any file. parasdua Linux - Newbie 6 04-22-2008 09:59 AM
Setting system date and time affecting the clock and date on BIOS satimis Ubuntu 7 09-21-2007 08:02 AM
what is the correct syntax order for tar with --after-date DATE, --newer DAT farhan Linux - General 1 03-16-2007 08:43 AM
thunderbird puts time instead of date under 'date' header wabbalee Linux - Software 4 11-26-2006 04:58 AM


All times are GMT -5. The time now is 06:36 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration