2011-12-21 8 views
6

कृपया ध्यान दें कि मैं का उपयोग नहीं कर सकते 'लगता है' लक्ष्य पर्यावरणबिना किसी लिनक्स शैल स्क्रिप्ट में दिनांक के आधार पर फ़ाइलों को मैं कैसे ढूंढ और हटा सकता हूं?

मैं एक linux खोल स्क्रिप्ट में 7 दिन से अधिक पुराने सभी फाइलों को नष्ट करने के लिए की जरूरत है। कुछ ऐसा:

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 

उपयोग करने के लिए कोशिश कर रहा था, लेकिन पता चला कि मैं लक्ष्य प्रणाली पर मिल उपयोग नहीं कर सकते (वहाँ क्रॉन प्रयोक्ता के लिए कोई अनुमति है और इसे बदला नहीं जा सकता है)। लक्ष्य प्रणाली Redhat Enterprise है।

फ़ाइल नाम इस प्रकार फ़ॉर्मेट कर रहे हैं:

gzip>/MNT/target03/बाकी के- पथ/वेब/बैकअप/DATABASENAME_ date "+%Y-%m-%d" .gz

उत्तर

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 1325559634 लीटर 1324944000 १३२५५५९६३५ lt 1324944000 १३२५५५९६३५ lt 1324944000 १३२५५५९६३५ lt 1324944000 १३२५५५९६३५ lt 1324944000 1325559635 लीटर 1324944000 1325559635 लीटर 1324944000 1325559635 लीटर 1324944000 1325559635 लीटर 1324944000 1325559635 लीटर 1324944000 1325559635 लीटर 1324944000 1325559635 लीटर 1324944000 1325559635 लीटर 1324944000 – codecowboy

+0

गूंज "rm -f $ f" कभी नहीं चलाने के लिए लगता है। फ़ाइलों को इस तरह नामित किया गया है - eewapwap01011-12-20.gz। क्या रेगेक्स इस फ़ाइल नाम को सही ढंग से पकड़ लेगा? – codecowboy

+0

यह बताता है कि ts = 'date -d $ date | दिनांक + "% s" 'ts =' date -d "$ date" + "% s" होना चाहिए, फिर स्क्रिप्ट काम करती है – codecowboy

8

यह काम करना चाहिए:

#!/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' फ़ाइल के संशोधित समय को फ़ाइल के लिए यूनिक्स युग के बाद सेकंड के रूप में देता है, और $(date +%s) वर्तमान यूनिक्स टाइमस्टैम्प देता है। फिर यह देखने के लिए बस एक साधारण जांच है कि फाइल का टाइमस्टैम्प, साथ ही सात दिन के लायक सेकंड, वर्तमान टाइमस्टैंप से अधिक है।

+0

धन्यवाद - के बारे में एक लापता ')' त्रुटियों हो रही है। $ अब उद्धरण में भी होना चाहिए? मैं $ (आरएम "$ फाइल") डाल रहा हूं जहां आपकी टिप्पणी है। – codecowboy

+0

आपको केवल 'आरएम "$ फ़ाइल डालना होगा" ' – pgl

+0

@pgl इस भयानक लिपि के लिए धन्यवाद, लेकिन यह व्यस्त बॉक्स पर काम नहीं करता है, इसे थोड़ा सा मालिश करने की आवश्यकता है, इसलिए यह है कि यह कैसे काम करता है: '#!/ Bin/श dir = "/ path// अपने/फ़ाइलें करने के लिए" अब = $ (तिथि +% s) दिन = 30 में फ़ाइल के लिए "$ DIR /" * करते हैं [$ ((('stat $ file -c '% y'') + (86400 * $ DAYS))) -एलटी $ अब] फिर # प्रक्रिया/आरएम/जो भी फ़ाइल ... फाई किया गया' – 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 दिन ':

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 

is_older दिनचर्या में, 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 

किया

संबंधित मुद्दे

 संबंधित मुद्दे