수정된 지 60일이 넘은 파일을 삭제하는 방법을 알고 있는데, 파일 이름의 타임스탬프를 기준으로 파일을 삭제하고 싶습니다.
예를 들어, 매월 매일 다음 파일이 있고 지난 3년 동안의 파일이 있습니다.
vtm_data_12month_20140301.txt
vtm_data_12month_20140301.control
vtm_mtd_20130622.txt
vtm_mtd_20130622.control
vtm_ytd_20131031.txt
vtm_ytd_20131031.control
60일보다 오래된 모든 파일(파일 이름 기준)을 찾은 다음 매월 마지막 파일을 제외한 모든 파일을 삭제하는 스크립트를 작성하고 싶습니다. 예를 들어 1월에는 을 제외한 모든 항목을 삭제하고 싶습니다 vtm_data_12month_20140131.txt
. 여기서 문제는 1월 30일 기준으로 파일을 받을 수도 있으니 그럴 경우 최신 파일을 삭제하면 안되고 나머지도 삭제해야 한다는 점입니다.
쉘 스크립트를 통해 이를 달성하는 방법을 알려주십시오.
답변1
좋아, 거꾸로 정렬하도록 스크립트를 다시 작성했는데 제대로 작동할 것 같습니다. 연도와 월을 이전 연도와 비교하여 낮을 경우 해당 월의 마지막 항목이어야 합니다.
#!/bin/bash
#the tac reverses the listing, so we go from newest to oldest, vital for our logic below
FILES=`ls | tac`
#create a cutoff date by taking current date minus our 60 day limit
CUTOFFDATE=`date --date="60 days ago" +%Y%m%d`
#we are setting this value to month 13 of the current year
LASTYEARMONTH=`date +%Y`13
for file in $FILES; do
#get datestamp
FILEDATE=`expr match "$file" '.*\(20[0-9][0-9][0-9][0-9][0-9][0-9]\)'`
#get year and month, ie 201410
THISYEARMONTH=${FILEDATE:0:6}
if [ ! -z $FILEDATE ] && [ $THISYEARMONTH -lt $LASTYEARMONTH ]; then
echo "$file IS THE LAST FILE OF THE MONTH. NOT DELETING"
else
#now we see if the file is older than 60 days (ie, has a LOWER unix timestamp than our cutoff)
if [ ! -z $FILEDATE ] && [ $FILEDATE -lt $CUTOFFDATE ]; then
echo "$file has a file date of $FILEDATE which is older than 60 days."
#uncomment this next line to remove
#rm $file
fi
fi
LASTYEARMONTH=$THISYEARMONTH
done
답변2
다음 코드는 매월 마지막 파일을 보관하지 않습니다.
#! /bin/bash
cmp_timestamp=$(date --date="60 days ago" +%Y%m%d)
while read filename; do
[[ $filename =~ _(20[0-9][0-9][01][0-9][0123][0-9])\. ]]
timestamp=${BASH_REMATCH[1]}
printf "%-40s : %s\n" "$filename" "${timestamp}"
if [ "$timestamp" -lt "$cmp_timestamp" ]; then
echo " delete this file"
: rm "$filename"
else
echo " DO NOT delete this file"
fi
echo
done <file
에서 man bash
:
BASH_REMATCH
An array variable whose members are assigned by the =~ binary operator to
the [[ conditional command. The element with index 0 is the portion of the
string matching the entire regular expression. The element with index n
is the portion of the string matching the nth parenthesized subexpression.
This variable is read-only.
답변3
while 루프에서 이것을 시도해 볼 수 있습니다:
#!/bin/bash
A=vtm_data_12month_20140301.txt
B=`ls vtm_data_12month_20140301.txt | awk -F "_" '{print $4}' | awk -F "." '{print $1}'`
C=`date --date="60 days ago" +%Y%m%d`
if [ "$B" < "$C" ]
then
rm -fr $A
else
echo "$A is not older"
fi
답변4
다음 Python 스크립트가 작업을 수행합니다. 변수를 사용하여 파일을 삭제해야 하는 일 수를 구성할 수 있습니다 days
.
#!/usr/bin/env python3
import os
import re
import datetime
days=60
delta = datetime.date.today() - datetime.timedelta(days=days)
files = [ x for x in os.listdir() if re.search('_\d{8}\.', x)]
for file in files:
date = re.search('_(\d{8})\.', file).group(1)
if datetime.datetime.strptime(date, '%Y%m%d').date() <= delta:
print('Removing file: ',file)
os.remove(file)
산출:
$ ./remove.py
Removing file: vtm_data_12month_20140301.txt
Removing file: vtm_mtd_20130622.control
Removing file: vtm_data_12month_20140301.control
Removing file: vtm_mtd_20130622.txt
Removing file: vtm_ytd_20131031.txt
Removing file: vtm_ytd_20131031.control