2011-12-21 20 views
6

私はLinuxのシェルスクリプトで7日間以上古いすべてのファイルを削除する必要がターゲット環境でLinuxのシェルスクリプト内の日付に基づいてファイルを見つけずに見つけて削除するにはどうしたらいいですか?

を「検索」使用することはできませんのでご注意ください。次のようなもの:

FILES=./path/to/dir 
for f in $FILES 
do 
    echo "Processing $f file..." 
    # take action on each file. $f store current file name 
    # perhaps stat each file to get the last modified date and then delete files with date older than today -7 days. 

done 

これを行うには「stat」を使用できますか?私は

find *.gz -mtime +7 -delete 

を使用しようとしているが、私は、ターゲットシステム上で見つける使用できないことが発見された(そこのcronのユーザーには許可されず、これを変更することはできません)。ターゲットシステムはRedhat Enterpriseです。ファイル名は次のようにフォーマットされている

答えて

3

ファイル名に時間を持っているので、その後相続人の時間にすることを行い、いくつかのコードの削除をそれを使用:このスクリプトはエポックからの秒数で現在の時刻を取得してから7日前のタイムスタンプを計算

を。次に各ファイルに対してファイル名を解析し、各ファイル名に埋め込まれた日付をタイムスタンプに変換し、タイムスタンプを比較して削除するファイルを決定します。タイムスタンプを使用すると、日付(閏年、月の別の日など)を直接扱うことで面倒をなくすことができます。

実際の削除はコメントアウトされているため、コードをテストできます。

#funciton to get timestamp X days prior to input timestamp 
# arg1 = number of days past input timestamp 
# arg2 = timestamp (e.g. 1324505111) seconds past epoch 
getTimestampDaysInPast() { 
    daysinpast=$1 
    seconds=$2 
    while [ $daysinpast -gt 0 ] ; do 
    daysinpast=`expr $daysinpast - 1` 
    seconds=`expr $seconds - 86400` 
    done 
# make midnight 
    mod=`expr $seconds % 86400` 
    seconds=`expr $seconds - $mod` 
    echo $seconds 
} 
# get current time in seconds since epoch 
getCurrentTime() { 
    echo `date +"%s"` 
} 

# parse format and convert time to timestamp 
# e.g. 2011-12-23 -> 1324505111 
# arg1 = filename with date string in format %Y-%m-%d 
getFileTimestamp() { 
    filename=$1 
    date=`echo $filename | sed "s/[^0-9\-]*\([0-9\-]*\).*/\1/g"` 
    ts=`date -d $date | date +"%s"` 
    echo $ts 
} 

########################### MAIN ############################ 
# Expect directory where files are to be deleted to be first 
# arg on commandline. If not provided then use current working 
# directory 

FILEDIR=`pwd` 
if [ $# -gt 0 ] ; then 
    FILEDIR=$1 
fi 
cd $FILEDIR 

now=`getCurrentTime` 
mustBeBefore=`getTimestampDaysInPast 7 $now` 
SAVEIFS=$IFS 
# need this to loop around spaces with filenames 
IFS=$(echo -en "\n\b") 
# for safety change this glob to something more restrictive 
for f in * ; do 
    filetime=`getFileTimestamp $f` 
    echo "$filetime lt $mustBeBefore" 
    if [ $filetime -lt $mustBeBefore ] ; then 
    # uncomment this when you have tested this on your system 
    echo "rm -f $f" 
    fi 
done 
# only need this if you are going to be doing something else 
IFS=$SAVEIFS 
+0

私は持っていますこのコードを使用して試みたが、単にこの出力を得る:1325559634 1324944000 LT 1325559634 LT 1324944000 1325559635 LT 1324944000 1325559635 1324944000 LT 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 1325559635 LT 1324944000 – codecowboy

+0

エコー "のrm -f $ F" を実行すると思われることはありません。ファイルは次のようになります - eeSwap_2011-12-20.gz正規表現はこのファイル名を正しくキャッチしますか? – codecowboy

+0

それはts = 'date -d $ date | date + "%s"はts = 'date -d" $ date "+"%s "'にする必要があります。 – codecowboy

8

.gzを

のgzip>を/ mnt/target03 /残り-のパス/ウェブ/バックアップ/ DATABASENAME_ date "+%Y-%m-%d"これは動作するはずです:

#!/bin/sh 

DIR="/path/to/your/files" 
now=$(date +%s) 
DAYS=30 

for file in "$DIR/"* 
do 
    if [ $(((`stat $file -c '%Y'`) + (86400 * $DAYS))) -lt $now ] 
    then 
    # process/rm/whatever the file... 
    fi 
done 

説明のビット:stat <file> -c '%Z'は、ファイルの変更日時をファイルのUNIXエポックからの秒数で示し、$(date +%s)は現在のUNIXタイムスタンプを示します。次に、ファイルのタイムスタンプと7日分の秒が現在のタイムスタンプより大きいかどうかを調べるだけの簡単なチェックがあります。

+0

感謝をし - ')' 行方不明に関するエラーを取得しています。 $も引用符で囲まなければなりませんか?あなたのコメントがどこにあるのか$(rm "$ file")を入れています。 – codecowboy

+0

'rm"を置く必要があるのは$ファイル " – pgl

+0

@pglです。このすばらしいスクリプトをありがとうございますが、ビジーボックスでは機能しませんでしたので、ちょっとマッサージする必要がありましたので、フォームの仕組みを教えてください: '#!/ binに/ shの DIR = "/パス/に/あなた/ファイル" 今すぐ= $(日付+%s)は DAYS = 30 "$ DIR /" 内のファイルのための* [$(場合 を行います($ stats $ file -c '%Y')+(86400 * $ DAYS)))-lt $ now] then #何らかのプロセス/ rm /ファイル... fi done' – valentt

2

あなたはファイル名に日付に依存することを好む場合は、このルーチンを使用することができ、日付が別のより古いかどうかを確認する:

is_older(){ 
    local dtcmp=`date -d "$1" +%Y%m%d`; shift 
    local today=`date -d "$*" +%Y%m%d` 
    return `test $((today - dtcmp)) -gt 0` 
} 

とファイル名通じ、その後することができますループ、「合格 - 二日として7日:is_olderルーチンで

for filename in *; 
do 
    dt_file=`echo $filename | grep -o -E '[12][0-9]{3}(-[0-9]{2}){2}'` 
    if is_older "$dt_file" -7 days; then 
     # rm $filename or whatever 
    fi 
done 

date -d "-7 days" +%Y%m%dは、比較のために準備数値形式で、7日前の日付を返します。

0
DIR='' 

now=$(date +%s) 

for file in "$DIR/"* 
do 
echo $(($(stat "$file" -c '%Z') + $((86400 * 7)))) 
echo "----------" 
echo $now 

関連する問題