我正在编写一个shell脚本,用于检索目录中最后一次修改x天前的所有文件,从当天的00:00开始。
我用于此操作的当前find命令如下所示,但它将从脚本运行时开始检查。例如,如果脚本在12:00运行并检索到7天前或7天前修改的所有文件,则查找结果中将不包括7天前12:00之后修改的所有文件。
find $SEARCH_DIR -mtime +$DAYS_AGO
我知道在Bash中,您可以使用-daystart和find来克服这一问题,但该脚本需要在使用/bin/shshell的IBM z/OS机器上运行,该机器不支持此选项。
我看到过其他情况,人们使用touch创建文件,并使用date-d或date-date将时间戳更改为所需日期,如下所示,但这些选项对我来说仍然是不可用的。
date -d '7 days ago'
date --date '3 months 1 day ago'
此PDF显示了我们的IBM z/OS版本支持的UNIX命令的完整列表:http://publibfp.dhe.ibm.com/epubs/pdf/bpxza5c0.pdf
有人对如何克服这个问题有什么想法吗?如有任何建议,我们将不胜感激。
提前感谢!
此页面显示了各种符合POSIX的方法来获取自epoch以来的当前秒数。最简单的使用awk
,它使用当前时间作为默认的随机数种子:
epoch_time=$(awk 'BEGIN { srand(); print srand() }' < /dev/null)
从这里,您可以算术地操纵当前时间:
# 7 days ago
ts=$(( epoch_time - 7 * 24 * 60 * 60 ))
像"3个月,1天"这样的事情会很棘手,因为GNU对一个月的定义只是"与今天相同的一天,但在前一个月,所以它不能很容易地转换为固定的秒数
尝试此find . -mmin $(($(date +"%s") % (60*60*24) / 60 + 7*24*60))
解释:
date +"%s" #get current unix time_stamp
$(date +"%s") % (60*60*24) / 60 #get minutes offset from day start
$(($(date +"%s") % (60*60*24) / 60 + 7*24*60))
#get minutes offset from day start of 7 days ago
find . -mmin $(($(date +"%s") % (60*60*24) / 60 + 7*24*60))
#-mmin file’s data was last modified n minutes ago.
在过去的好日子里,我们通过操纵时区来进行一些简单的日期运算。你需要找到你的TZ是什么,然后你可以用24小时来抵消它,回到1天,等等。
为了简化,假设我们处于TZ=GMT0。然后在午夜查找超过1天的文件:
date=`TZ=GMT24 date +%Y%m%d`
touch -t ${date}0000 reffile
find $SEARCH_DIR ! -newer reffile ...
让我们知道TZ=GMT48是否能将日期向后移动2天,依此类推。
你的问题确实说shell脚本,但你能求助于编译一些C吗?这个小程序将获取一个文件名,并将修改后的时间移回午夜前一天的。将-1
更改为天数。然后您可以创建一个文件,用这个程序"触摸"它,并使用find ... ! -newer file
。
/* reset time modified to 1 day back midnight */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
pexit(char *s){
perror(s);
exit(1);
}
main(int argc,char **argv){
char *file;
struct stat buf;
time_t timeoff = -1L*24*60*60; /* one day back */
struct timeval tvp[2];
struct tm *tmp;
if(argc!=2)pexit("usage: file to untouch. not ");
file = argv[1];
if(lstat(file,&buf)<0)pexit("cannot lstat file");
tmp = localtime(&buf.st_mtime);
timeoff -= tmp->tm_sec+(tmp->tm_min+tmp->tm_hour*60)*60; /* midnight */
tvp[0].tv_sec = buf.st_atime;
tvp[0].tv_usec = 0;
tvp[1].tv_sec = buf.st_mtime + timeoff;
tvp[1].tv_usec = 0;
if(utimes(file, tvp)<0)pexit("cannot change time");
}