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.

4 Answers 4


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 < $four_days )) && rm "$f"
  • GNU date commands not working.. :( Any other way to get date which is 5 days before?
    – Nalu
    May 8, 2012 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, 2012 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, 2012 at 7:14
  • Question remains: what commands do you have available to get the current date?
    – Bram
    May 8, 2012 at 8:47
  • If Tcl is installed: four_days=$(echo "puts [clock format [clock scan {4 days ago}] -format %Y%m%d]" | tclsh) May 8, 2012 at 13:05

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
     [[ $DATE -le $THRESHOLD ]] && rm -v $FILE
  • GNU date commands not working.. :( Any other way to get date which is 5 days before?
    – Nalu
    May 8, 2012 at 6:04

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:


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

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
  • 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, 2012 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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