Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to delete log files which are older than 5 days from a directory. But deletion should not be based on the timestamp of file. It should be based on the name of file. For Example todays date is 07/05/2012 and the directory contains 10 files of names like ABC_20120430.log, ABC_20120429.log, ABC_20120502.log, ABC_20120320.log etc. I want to be able to remove the files by extracting the date from the name of the file.

share|improve this question

migrated from stackoverflow.com May 7 '12 at 11:54

This question came from our site for professional and enthusiast programmers.

4 Answers 4

up vote 2 down vote accepted

Based on date from filename:

THRESHOLD=$(date -d "5 days ago" +%Y%m%d)
ls -1 ABC_????????.log | 
  sed 'h;s/[_.]/ /g;G;s/\n/ /' | 
  while read A DATE B FILE
  do 
     [[ $DATE -le $THRESHOLD ]] && rm -v $FILE
  done
share|improve this answer
    
GNU date commands not working.. :( Any other way to get date which is 5 days before? –  Nalu May 8 '12 at 6:04

I think @oHessling almost has it: Don't parse ls, and you can do more in bash:

four_days=$(date -d "4 days ago" +%Y%m%d)
for f in ABC_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].log; do
  date=${f#ABC_}
  date=${date%.log}
  (( $date < $four_days )) && rm "$f"
done
share|improve this answer
    
GNU date commands not working.. :( Any other way to get date which is 5 days before? –  Nalu May 8 '12 at 6:04
1  
@Naren: what OS are you on? If you don't have GNU date, we need to know what you do have. –  Mat May 8 '12 at 6:30
    
With help of uname -a got the following info: "SunOS badap01t 5.10 Generic_141444-09 sun4u sparc SUNW,SPARC-Enterprise" –  Nalu May 8 '12 at 7:14
    
Question remains: what commands do you have available to get the current date? –  Bram May 8 '12 at 8:47
    
If Tcl is installed: four_days=$(echo "puts [clock format [clock scan {4 days ago}] -format %Y%m%d]" | tclsh) –  glenn jackman May 8 '12 at 13:05

One way using perl:

Content of script.pl:

use warnings;
use strict;
use Time::Local qw/timelocal/;
use File::Spec;

## Process all input files.
while ( my $file = shift @ARGV ) { 

    ## Remove last '\n'.
    chomp $file;

    ## Extract date from file name.
    my ($date) = $file =~ m/.*_([^.]+)/ or next;

    ## Extract year, month and day from date.
    my ($y,$m,$d) = $date =~ m/(\d{4})(\d{2})(\d{2})/ or next;

    ## Get date in seconds.
    my $time = timelocal 0, 0, 0, $d, $m - 1, $y - 1900 or next;

    ## Get date in seconds five days ago.
    my $time_5_days_ago = time - 5 * 24 * 3600;

    ## Substract them, and if it is older delete it and print the
    ## event.
    if ( $time - $time_5_days_ago < 0 ) { 
        unlink File::Spec->rel2abs( $file ) and printf qq[%s\n], qq[File $file deleted];
    }   
}

To test it I create some files:

touch ABC_20120430.log ABC_20120502.log ABC_20120320.log ABC_20120508.log ABC_20120509.log

Check them with ls -1:

ABC_20120320.log                                                                                                                                                                                                                             
ABC_20120430.log                                                                                                                                                                                                                             
ABC_20120502.log                                                                                                                                                                                                                             
ABC_20120508.log                                                                                                                                                                                                                             
ABC_20120509.log                                                                                                                                                                                                                             
script.pl

Run the script like:

perl script.pl *.log

With following output:

File ABC_20120320.log deleted
File ABC_20120430.log deleted
File ABC_20120502.log deleted
share|improve this answer

What you could do instead is use the fact that your filenames will sort in chronological order. For instance, to keep the last 5 files:

ls ABC_????????.log | head -n-5 | xargs rm
share|improve this answer
3  
Don't use xargs with rm unless you know you are killing kittens every time you do. It's just a bad idea, if you don't know why do some research and learn that there are always better ways to approach any problem that this could be a solution for. –  Caleb May 7 '12 at 12:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.