如何在没有find的Linux shell脚本中根据日期查找和删除文件?

wko9yo5t  于 12个月前  发布在  Shell
关注(0)|答案(4)|浏览(101)

请注意,我不能在目标环境中使用'find'

我需要删除所有文件超过7天旧的Linux shell脚本。比如说:

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

但是发现我不能在目标系统上使用find(cron用户没有权限,这不能更改)。目标系统是红帽企业号
文件名的格式如下:
gzip > /mnt/target03/rest-of-path/web/backups/DATABASE ENAME_ date "+%Y-%m-%d" .gz

9lowa7mx

9lowa7mx1#

这应该是可行的:

#!/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时间戳。然后只需简单地检查文件的时间戳加上30天的秒数是否大于当前时间戳。

1l5u6lss

1l5u6lss2#

因为你在文件名中有时间,然后使用它来计时删除,这里有一些代码可以做到这一点:
此脚本获取自epoch以来的当前时间(以秒为单位),然后计算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
mznpcxlj

mznpcxlj3#

如果你喜欢依赖文件名中的日期,你可以使用这个例程,检查一个日期是否比另一个日期早:

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 days'作为第二个日期:

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天前的日期,以供比较。

b4lqfgs4

b4lqfgs44#

DIR=''

now=$(date +%s)

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

相关问题