以下のログファイルがあるとしましょう。
AA_XX_20130719185428.log
exec_xxx_cpb_20130712182453.log
13122013121327_AR_INC_DOBC_1.dprf.log
24122013_masterscript.LOG
日付部分には、日付と時刻の両方が含まれます。
2か月前のファイルをすべて削除したい。
最終変更日ではなく、ファイル名に含まれている日付に基づいてファイルを削除したくありません。日付は次のいずれかの形式にすることができます。
シェルスクリプトを使用してファイルを削除するにはどうすればよいですか?
次のスクリプトを使用できます。ファイル名を指定して呼び出し、引数としてテストおよび削除します。
#!/usr/bin/env python
# encoding: utf-8
import os
import sys
import datetime
test_file_names = [x for x in """\
AA_XX_20130719185428.log
exec_xxx_cpb_20130712182453.log
13122013121327_AR_INC_DOBC_1.dprf.log
24122013_masterscript.LOG
""".split('\n') if x.strip()]
# appr. 2 meses
two_months = datetime.date.today() - datetime.timedelta(days=61)
testing = len(sys.argv) < 2
if testing:
file_names = test_file_names
else:
file_names = sys.argv[1:]
allow_datetime = set([
len('YYYYmmddHHMMSS'),
len('ddmmYYYYHHMMSS'),
len('ddmmYYYY'),
])
for file_name in test_file_names:
for part in os.path.splitext(os.path.basename(file_name))[0].split('_'):
if len(part) not in allow_datetime:
continue
for ch in part:
if not ch.isdigit():
break
else:
dt = part
if dt[4:6] == '20': # ddmmYYYY
yy = int(dt[4:8])
mm = int(dt[2:4])
dd = int(dt[:2])
else: # YYYYmmdd
yy = int(dt[:4])
mm = int(dt[4:6])
dd = int(dt[6:8])
try:
d = datetime.date(yy, mm, dd)
except ValueError:
print 'wrong date', yy, mm, dd
raise
if testing:
print '{:<6s} {:<40s} {}'.format(
'remove' if d < two_months else ' ', file_name, repr(d))
Elif d < two_months:
print 'removing', file_name
os.remove(file_name)
GNU date
を使用している場合は、日付操作機能を利用できます。
#!/usr/bin/env bash
## Define the age limit
lim=$(date -d "2 months ago" +%s);
## Find all files in the current directory and
## sub directories
find . -type f |
## Extract the longest string of numbers (we assume that is the date)
## and change mmdd to ddmm
Perl -lne '
## skip file names that don't have enough numbers
/(\d{1,8})/ || next; $d=$1;
next unless $d;
## Change YYYYmmddHHMMSS to mm/dd/YYY
if($d=~/201\d$/){$d=~s|(\d{2})(\d{2})(\d{4})|$2/$1/$3|}
## Change ddmmYYYYHHMMSS or ddmmYYYY to mm/dd/YYY
else{$d=~s|(\d{4})(\d{2})(\d{2})|$2/$3/$1|};
## Print the original file name and the modified date string
print "$_ $d" if
' |
## Read the file name into $f and the date into $d
while read f d; do
## If this date is older than $lim, delete the file
if [ "$(date -d "$d" +%s)" -lt "$lim" ]; then
rm "$f";
fi
done
これは、ターミナルに直接コピーして貼り付けることができる「ワンライナー」に凝縮できます。
lim=$(date -d "2 months ago" +%s);
find . -type f | Perl -lne '
/(\d{1,8})/ || next; $d=$1;
if($d=~/201\d$/){$d=~s|(\d{2})(\d{2})(\d{4})|$2/$1/$3|}
else{$d=~s|(\d{4})(\d{2})(\d{2})|$2/$3/$1|}; print "$_ $d"' |
while read f d; do [ "$(date -d "$d" +%s)" -lt "$lim" ] && echo rm "$f"; done