2012-07-23 37 views
5

我以前曾用一個簡單的find命令來刪除tar文件未在最近x天內訪問(在這個例子中,3天)來限制一個目錄的大小我現在需要通過刪除訪問日期的順序來改進這個腳本,而我的bash寫作技巧有點生疏。這就是我需要做的:bash腳本刪除上次訪問文件

  1. 檢查目錄/路徑的大小/ TO /文件
  2. 如果在1大小)比X尺寸更大,獲得通過訪問日期
  3. 的文件列表
  4. 刪除,以便文件,直到大小小於X

這樣做的好處是高速緩存和備份目錄,我只會刪除什麼,我需要保持它在一個限度內,而簡單的方法可能去了如果一天特別大,則限制大小。我猜我需要使用stat和bash for循環?

回答

4

這裏有一個簡單,易於閱讀和理解方法,我想出了這樣做:

DIRSIZE=$(du -s /PATH/TO/FILES | awk '{print $1}') 
if [ "$DIRSIZE" -gt "$SOMELIMIT" ] 
    then 
    for f in `ls -rt --time=atime /PATH/TO/FILES/*.tar`; do 
    FILESIZE=`stat -c "%s" $f` 
    FILESIZE=$(($FILESIZE/1024)) 

    DIRSIZE=$(($DIRSIZE - $FILESIZE)) 
    if [ "$DIRSIZE" -lt "$LIMITSIZE" ]; then 
     break 
    fi 
done 
fi 
+1

我認爲這個腳本是一個好的開始,但它並沒有真正回答這個問題。您詢問如何刪除文件,以便目錄大小低於閾值。您的答案似乎並未真正刪除任何內容,只是對文件進行排序並循環播放。看起來你在這裏丟失了一個「rm」。 – 2015-07-17 23:34:08

1

我不需要使用循環,只需謹慎地應用stat和awk。下面的細節和解釋,首先是代碼:

find /PATH/TO/FILES -name '*.tar' -type f \ 
| sed 's/ /\\ /g' \ 
| xargs stat -f "%a::%z::%N" \ 
| sort -r \ 
| awk ' 
    BEGIN{curSize=0; FS="::"} 
    {curSize += $2} 
    curSize > $X_SIZE{print $3} 
    ' 
| sed 's/ /\\ /g' \ 
| xargs rm 

請注意,這是一個邏輯命令行,但爲了理智,我將它分開。

它以基於上述命令的find命令開始,沒有將其限制爲超過3天的文件的部分。它將它管理爲sed,以便在文件名稱查找返回中轉義任何空格,然後使用xargs在所有結果上運行統計信息。 -f「%a ::%z ::%N」告訴stat要使用的格式,第一個字段中上次訪問的時間,第二個中文件的大小以及第二個文件中的文件名第三。我用'::'來分隔字段,因爲用這種方式處理文件名中的空格更容易。排序然後將它們排序在第一個字段上,用-r來顛倒排序。

現在我們列出了我們感興趣的所有文件,從最新訪問到最早訪問的順序。然後,awk腳本在列表中加入所有大小,並在超過$ X_SIZE時開始輸出它們。不以這種方式輸出的文件將保留,其他文件名將再次轉到sed以轉義任何空格,然後轉換爲運行rm的xargs。

+0

這個解決方案沒有奏效。我改進了腳本並將結果作爲單獨的答案發布。 – 2012-08-16 11:14:03

+0

這個想法很好。謝謝。 – 2012-08-16 11:14:24

6

我提高brunner314的例子並固定在它的問題。

這裏是我使用的是工作腳本:

#!/bin/bash 
DELETEDIR="$1" 
MAXSIZE="$2" 
if [[ -z "$DELETEDIR" || -z "$MAXSIZE" || "$MAXSIZE" -lt 1 ]]; then 
    echo "usage: $0 [directory] [maxsize in megabytes]" >&2 
    exit 1 
fi 
find "$DELETEDIR" -type f -printf "%[email protected]::%p::%s\n" \ 
| sort -rn \ 
| awk -v maxbytes="$((1024 * 1024 * $MAXSIZE))" -F "::" ' 
    BEGIN { curSize=0; } 
    { 
    curSize += $3; 
    if (curSize > maxbytes) { print $2; } 
    } 
    ' \ 
    | tac | awk '{printf "%s\0",$0}' | xargs -0 -r rm 
# delete empty directories 
find "$DELETEDIR" -mindepth 1 -depth -type d -empty -exec rmdir "{}" \;