我想从目录中删除超过 5 天的日志文件。但删除不应该基于文件的时间戳。它应该基于文件名。例如,今天的日期是 07/05/2012,该目录包含 10 个名称为ABC_20120430.log
、ABC_20120429.log
、等的文件。我希望能够通过从文件名中提取日期来删除这些文件ABC_20120502.log
。ABC_20120320.log
答案1
我认为@oHessling几乎有它:不解析 ls,你可以在 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
答案2
基于文件名的日期:
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
答案3
一种使用方法perl
:
内容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];
}
}
为了测试它,我创建了一些文件:
touch ABC_20120430.log ABC_20120502.log ABC_20120320.log ABC_20120508.log ABC_20120509.log
检查它们ls -1
:
ABC_20120320.log
ABC_20120430.log
ABC_20120502.log
ABC_20120508.log
ABC_20120509.log
script.pl
运行脚本如下:
perl script.pl *.log
具有以下输出:
File ABC_20120320.log deleted
File ABC_20120430.log deleted
File ABC_20120502.log deleted
答案4
您可以做的是利用文件名将按时间顺序排序的事实。例如,要保留最后 5 个文件:
ls ABC_????????.log | head -n-5 | xargs rm