我很清楚可以通过
find myfile.txt -mtime +5
检查我的文件是否超过 5 天。不过,我想获取 myfile.txt 中的 mtime 并将其存储到变量中以供进一步使用。我该怎么做?
stat
可以为您提供该信息:
filemtime=$(stat -c %Y myfile.txt)
%Y
为您提供最后一次修改为“自纪元以来的秒数”,但还有很多其他选项; 更多信息。因此,如果该文件于 2011 年 1 月 22 日 15:30 GMT 进行了修改,则上述命令将返回 1295710237 区域中的数字。
编辑:啊,你想要修改后的天数。这会变得更加复杂,尤其是因为“天”不是一个固定的时间段(有些“天”只有 23 小时,其他“天”有 25 小时 - 由于夏令时)。
naive版本可能看起来像这样:
filemtime=$(stat -c %Y "$1")
currtime=$(date +%s)
diff=$(( (currtime - filemtime) / 86400 ))
echo $diff
...但同样,假设一天的长度始终为 86,400 秒。
有关 bash 中算术的更多信息这里。
日期实用程序有一个方便的开关,用于从文件中提取 mtime,然后您可以使用格式字符串显示或存储该文件。
date -r file "+%F"
# 2021-01-12
file_mtime=$(date -r file "+%F")
参见
man date
,日期的输出由以"+"
开头的格式字符串控制
用于比较多个日期的有用格式字符串可能包括:
"+%j": day of year
"+%s": unix epoch time
日期算术在 bash 中有点麻烦,所以如果你需要在所有极端情况下都有效的相对时间,那么使用另一种语言可能会更好。
AGE=$(perl -e 'print -M $ARGV[0]' $file)
会将 $AGE 设置为 $file 的年龄(以天为单位),因为 Perl 的
-M
运算符会为您处理 stat
调用并转换为天数。
返回值为浮点值(例如6.62849537天)。如果需要整数结果,请在表达式中添加
int
AGE=$(perl -e 'print int -M $ARGV[0]' $file)
Ruby 和 Python 也有它们的单行代码来统计文件并返回一些数据,但我相信 Perl 拥有最简洁的方法。
这就是答案吗?
A=$(stat -c "%y" myfile.txt)
查看统计帮助
stat --help
Usage: stat [OPTION]... FILE...
Display file or file system status.
[...]
-c --format=FORMAT use the specified FORMAT instead of the default;
output a newline after each use of FORMAT
[...]
The valid format sequences for files
[...]
%y Time of last modification, human-readable
%Y Time of last modification, seconds since Epoch
[...]
除了已经提到的有些日子有 23 小时,有些日子有 25 小时之外,这个问题还有一些模糊的成分。我们可以通过说“平均一天是 24 小时”来暂时修复该部分。
即便如此,我们也需要定义“一天”的含义。这里有 3 种可能性:
mtime
提交了文件,现在已经是 6 小时后了。我们马上就会说这是零日,即同一天。但是,如果文件的 mtime
是太平洋夏令时间晚上 7 点,而 6 小时后,则为太平洋夏令时间 4 月 2 日凌晨 1 点。已经一天了?此外,必须指定时区,并且如果不同时区必须标准化为相同时区。一天可能由存储文件的本地日历或计算执行位置的 mtime
决定。如果文件在洛杉矶并在纽约市进行检查,那么每天有三个小时,就会多一天的差异。正如其他地方提到的,从秒到天的计算需要考虑从标准时间到夏令时的时间变化天数,但仅当时间在所需时区凌晨 2 点的几个小时内时才需要关注。
这是基于本地计算的 UNIX 纪元的解决方案:if [ $(date -d $(stat -c '@%Y' myfile.txt) '+%Y%m%d') -lt $(date -d '-5 days' '+%Y%m%d') ]
then
is_older=1
else
is_older=0
fi
echo $is_older
mtime
至少为 12 小时前以及此后每 24 小时一次。 (伪代码)number_days = round((now_in_secs - mtime_in_secs) / secs_per_average_day)
mtime
至少为 24 小时前以及此后每 24 小时一次。 (伪代码)number_days = floor((now_in_secs - mtime_in_secs) / secs_per_average_day)