PLEASE NOTE THAT I CANNOT USE 'find' IN THE TARGET ENVIRONMENT
请注意,我不能在目标环境中使用“找到”
I need to delete all files more than 7 days old in a linux shell script. SOmething like:
我需要在linux shell脚本中删除超过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
Can I use 'stat' to do this? I was trying to use
我可以用'stat'来做这个吗?我试图用
find *.gz -mtime +7 -delete
but discovered that I cannot use find on the target system (there is no permission for the cron user and this can't be changed). Target system is Redhat Enterprise.
但发现我不能在目标系统上使用find(没有cron用户的权限,这是无法更改的)。目标系统是Redhat Enterprise。
The file names are formatted like this:
文件名的格式如下:
gzip > /mnt/target03/rest-of-path/web/backups/DATABASENAME_date "+%Y-%m-%d"
.gz
gzip> / mnt / target03 / rest-of-path / web / backups / DATABASENAME_date“+%Y-%m-%d”.gz
4 个解决方案
#1
3
Since you have time in the filename then use that to time the deletion heres some code that does that :
由于你在文件名中有时间,然后使用它来删除时间,这是一些代码:
This script gets the current time in seconds since epoch and then calculates the timestamp 7 days ago. Then for each file parses the filename and converts the date embeded in each filename to a timestamp then compares timestamps to determine which files to delete. Using timestamps gets rid of all hassles with working with dates directly (leap year, different days in months, etc )
此脚本获取自纪元以来的当前时间(以秒为单位),然后计算7天前的时间戳。然后,对于每个文件,解析文件名并将每个文件名中嵌入的日期转换为时间戳,然后比较时间戳以确定要删除的文件。使用时间戳消除了直接处理日期的所有麻烦(闰年,几个月不同的日子等)
The actual remove is commented out so you can test the code.
实际删除已注释掉,因此您可以测试代码。
#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
#2
8
This should work:
这应该工作:
#!/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
A bit of explanation: stat <file> -c '%Z'
gives the modification time of the file as seconds since the UNIX epoch for a file, and $(date +%s)
gives the current UNIX timestamp. Then there's just a simple check to see whether the file's timestamp, plus seven days' worth of seconds, is greater than the current timestamp.
一点解释:stat
#3
2
If you prefer to rely on the date in the filenames, you can use this routine, that checks if a date is older than another:
如果您更喜欢依赖文件名中的日期,则可以使用此例程检查日期是否早于另一个:
is_older(){
local dtcmp=`date -d "$1" +%Y%m%d`; shift
local today=`date -d "$*" +%Y%m%d`
return `test $((today - dtcmp)) -gt 0`
}
and then you can loop through filenames, passing '-7 days' as the second date:
然后你可以遍历文件名,传递'-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
In is_older
routine, date -d "-7 days" +%Y%m%d
will return the date of 7 days before, in numeric format ready for the comparison.
在is_older例程中,日期-d“-7天”+%Y%m%d将返回7天前的日期,以数字格式准备进行比较。
#4
0
DIR=''
now=$(date +%s)
for file in "$DIR/"*
do
echo $(($(stat "$file" -c '%Z') + $((86400 * 7))))
echo "----------"
echo $now
done
#1
3
Since you have time in the filename then use that to time the deletion heres some code that does that :
由于你在文件名中有时间,然后使用它来删除时间,这是一些代码:
This script gets the current time in seconds since epoch and then calculates the timestamp 7 days ago. Then for each file parses the filename and converts the date embeded in each filename to a timestamp then compares timestamps to determine which files to delete. Using timestamps gets rid of all hassles with working with dates directly (leap year, different days in months, etc )
此脚本获取自纪元以来的当前时间(以秒为单位),然后计算7天前的时间戳。然后,对于每个文件,解析文件名并将每个文件名中嵌入的日期转换为时间戳,然后比较时间戳以确定要删除的文件。使用时间戳消除了直接处理日期的所有麻烦(闰年,几个月不同的日子等)
The actual remove is commented out so you can test the code.
实际删除已注释掉,因此您可以测试代码。
#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
#2
8
This should work:
这应该工作:
#!/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
A bit of explanation: stat <file> -c '%Z'
gives the modification time of the file as seconds since the UNIX epoch for a file, and $(date +%s)
gives the current UNIX timestamp. Then there's just a simple check to see whether the file's timestamp, plus seven days' worth of seconds, is greater than the current timestamp.
一点解释:stat
#3
2
If you prefer to rely on the date in the filenames, you can use this routine, that checks if a date is older than another:
如果您更喜欢依赖文件名中的日期,则可以使用此例程检查日期是否早于另一个:
is_older(){
local dtcmp=`date -d "$1" +%Y%m%d`; shift
local today=`date -d "$*" +%Y%m%d`
return `test $((today - dtcmp)) -gt 0`
}
and then you can loop through filenames, passing '-7 days' as the second date:
然后你可以遍历文件名,传递'-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
In is_older
routine, date -d "-7 days" +%Y%m%d
will return the date of 7 days before, in numeric format ready for the comparison.
在is_older例程中,日期-d“-7天”+%Y%m%d将返回7天前的日期,以数字格式准备进行比较。
#4
0
DIR=''
now=$(date +%s)
for file in "$DIR/"*
do
echo $(($(stat "$file" -c '%Z') + $((86400 * 7))))
echo "----------"
echo $now
done