Remove arquivos com mais de 5 dias no UNIX (data no nome do arquivo, não timestamp)

10

Desejo excluir os arquivos de log com mais de 5 dias de um diretório. Mas a exclusão não deve se basear no timestamp do arquivo. Deve ser baseado no nome do arquivo. Por exemplo, a data de hoje é 07/05/2012 e o diretório contém 10 arquivos de nomes como ABC_20120430.log , ABC_20120429.log , ABC_20120502.log , ABC_20120320.log etc. Eu quero poder remover os arquivos extraindo a data de o nome do arquivo.

    
por Nalu 07.05.2012 / 11:18

4 respostas

2

Com base na data do nome do arquivo:

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
    
por 07.05.2012 / 11:40
7

Eu acho que @oHessling quase tem isso: Não analise ls , e você pode fazer mais no 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
    
por 07.05.2012 / 19:23
1

Uma maneira de usar perl :

Conteúdo de 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];
    }   
}

Para testar, crio alguns arquivos:

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

Verifique-os com ls -1 :

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

Execute o script como:

perl script.pl *.log

Com a seguinte saída:

File ABC_20120320.log deleted
File ABC_20120430.log deleted
File ABC_20120502.log deleted
    
por 10.05.2012 / 00:03
-1

O que você pode fazer é usar o fato de que seus nomes de arquivos serão classificados em ordem cronológica. Por exemplo, para manter os últimos 5 arquivos:

ls ABC_????????.log | head -n-5 | xargs rm
    
por 07.05.2012 / 11:26

Tags