2013-12-03 52 views
3

我有一個腳本,刪除數據庫轉儲是不是說X = 21從備份目錄天以上:刪除超過X天的所有文件,但至少保持在Y最小

DB_DUMP_DIR=/var/backups/dbs 
RETENTION=$((21*24*60)) # 3 weeks 

find ${DB_DUMP_DIR} -type f -mmin +${RETENTION} -delete 

但如果無論出於何種原因,數據庫轉儲作業都無法完成一段時間,所有轉儲最終都會被丟棄。所以作爲一個保障,我想保留至少最年輕的Y = 7次轉儲,即使它全部或部分大於21天。

我尋找的東西是比這麪條更優雅。

DB_DUMP_DIR=/var/backups/dbs 
RETENTION=$((21*24*60)) # 3 weeks 
KEEP=7 

find ${DB_DUMP_DIR} -type f -printf '%[email protected] %p\n' | \ # list all dumps with epoch 
sort -n | \           # sort by epoch, oldest 1st 
head --lines=-${KEEP} |\       # Remove youngest/bottom 7 dumps 
while read date filename ; do      # loop through the rest 
    find $filename -mmin +${RETENTION} -delete  # delete if older than 21 days 
done 

(此片段可能有小錯誤 - 忽略他們這是爲了說明我能想出自己,爲什麼我不t喜歡它)

編輯:查找選項「-mtime」是一次性的:「-mtime +21」實際上意味着「至少22天大」。這總讓我困惑,所以我使用-mmin代替。還有一次,但只有一分鐘。

回答

0

你可以做循環自己:我假設你

t21=$(date -d "21 days ago" +%s) 
cd "$DB_DUMP_DIR" 
for f in *; do 
    if (($(stat -c %Y "$f") <= $t21)); then 
     echo rm "$f" 
    fi 
done 

有GNU date

+0

感謝'date -d「21天前」+%s「,我不知道。所以在我的示例腳本中,我可以將while循環塊更改爲: [「$ {date%\。[0-9] *}」-lt「$ {t21}」] && echo rm $ {filename} –

+0

是。但是使用bash的[[]]'意味着你需要更少的引用:'[[$ {date%。*} -lt $ t21]]''。另外dot不是一個特殊的glob字符,所以你不必轉義它:'$ {date%\。[0-9] *}'意味着「刪除一個點後跟一個數字,後面跟零個或多個任意字符」。如果你想刪除嚴格的數字,你需要'shopt -s extglob'然後''{date%。*([0-9])}' - 見http://www.gnu.org/software/ bash/manual/bashref.html#模式匹配 –

2

使用find來獲取足夠老刪除所有文件,濾出$KEEP年輕與tail ,然後通過其餘的xargs

find ${DB_DUMP_DIR} -type f -printf '%[email protected] %p\n' -mmin +$RETENTION | 
    sort -nr | tail -n +$KEEP | 
    xargs -r echo 

更換echorm如果報告的文件的列表要刪除列表中。

(我假設沒有轉儲文件有換行符他們的名字。)

+0

這個(就像David的答案)一樣,即使不需要,也會留下7個大於$ RETENTION的文件。 請注意,「tail -n + $ KEEP」是一次性的,它應該是「tail -n + $((KEEP + 1))」 我喜歡「xargs」,我會和它一起玩。儘管人們仍然必須剝奪時代。 –

1

可以使用-mtime代替-mmin這意味着你不必計算一天的分鐘數:

find $DB_DUMP_DIR -type f -mtime +21 

而不是刪除它們,你可以使用stat命令,以便對文件進行排序:

find $DB_DUMP_DIR -type f -mtime +21 | while read file 
do 
    stat -f "%-10m %40N" $file 
done | sort | awk 'NR > 7 {print $2}' 

這將列出超過21天的所有文件,但不包括超過21天的7個最小的文件。

從那裏,你可以喂到這個xargs的做刪除:

find $DB_DUMP_DIR -type f -mtime +21 | while read file 
do 
    stat -f "%-10m %40N" $file 
done | sort | awk 'NR > 7 {print $2]' | xargs rm 

當然,這一切都是假設你沒有在文件名中的空格。如果你這樣做,你將不得不採取稍微不同的方針。

這也將保留21天以上的七個最年輕的文件。你可能有比這更年輕的文件,並不想真正保留這些文件。但是,你可以簡單地再次運行相同的序列(除刪除-mtime參數:

find $DB_DUMP_DIR -type f | while read file 
do 
    stat -f "%-10m %40N" $file 
done | sort | awk 'NR > 7 {print $2} | xargs rm 

你需要看看你的stat命令來查看哪些選項是格式這從系統而異。我使用的是OS X.Linux是不同的。


讓我們採取一種稍微不同的方法。我還沒有徹底測試這一點,但:

如果所有的文件都在同一目錄中,並沒有一個文件名中都有空白:

ls -t | awk 'NR > 7 {print $0}' 

將打印出的所有文件除七個最年輕的文件。也許我們可以一起去?

current_seconds=$(date +%S) # Seconds since the epoch 
((days = 60 * 60 * 24 * 21)) # Number of seconds in 21 days 
((oldest_allowed = $current_seconds - $days)) # Oldest allowed file 
ls -t | awk 'NR > 7 {print $0}' | stat -f "%Dm %N" $file | while date file 
do 
    [ $date < $oldest_allowed ] || rm $file 
done 

ls ... | awk將刮掉七個最小的。之後,我們可以通過stat來獲取文件的名稱和日期。由於該日期是該時代之後的幾秒,所以我們必須計算當前時間之前21天的時間是在時代之前的秒數。

之後,它非常簡單。我們看看文件的日期。如果它比時代早21天(即時間戳較低),我們可以刪除它。

正如我所說的,我沒有徹底地測試過這個,但是這會在21天內刪除所有文件,並且只會在21天內刪除所有文件,但總是保留最年輕的七個。

+0

我不使用-mtime,因爲是一次性的:「-mtime +21」實際上意味着「至少22天以前」。這總是讓我困惑,所以我使用-mmin代替。大概仍然是一次性的,但我沒有時間離開我一分鐘。 –

+0

正如你所說,即使在不需要的時候,這也會讓我「超過21天的七個最老的文件」。最後的命令只會讓我成爲最年輕的7人。有趣的,但不回答我的問題。 –

+0

使用'find ... -printf「%T @%p」'可以刪除while-stat循環 –

0

我打開第二個答案,因爲我只是我有不同的解決方案 - 一個用awk:剛纔添加的時間到21天(以秒計)期間,減去當前時間,消除消極因素! (整理,從列表中移除最新7後):

DB_DUMP_DIR=/var/backups/dbs 
RETENTION=21*24*60*60 # 3 weeks 
CURR_TIME=`date +%s` 

find ${DB_DUMP_DIR} -type f -printf '%[email protected] %p\n' | \ 
    awk '{ print int($1) -'${CURR_TIME}' + '${RETENTION}' ":" $2}' | \ 
    sort -n | head -n -7 | grep '^-' | cut -d ':' -f 2- | xargs rm -rf 
0

以上答案都不很適合我,所以我適應chepner的答案,來到這一點,這只是保留了最後$KEEP備份。

find ${DB_DUMP_DIR} -printf '%[email protected] %p\n' | # print entries with creation time 
    sort -n |        # sort in date-ascending order 
    head -n -$KEEP |      # remove the $KEEP most recent entries 
    awk '{ print $2 }' |     # select the file paths 
    xargs -r rm       # remove the file paths 

相信chepner的代碼保留了$KEEP最古老,而不是最小的。

相關問題