使用 Bash 获取特定文件的 mtime?

问题描述 投票:0回答:5

我很清楚可以通过

find myfile.txt -mtime +5
检查我的文件是否超过 5 天。不过,我想获取 myfile.txt 中的 mtime 并将其存储到变量中以供进一步使用。我该怎么做?

linux bash shell
5个回答
83
投票

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 中算术的更多信息这里


9
投票

日期实用程序有一个方便的开关,用于从文件中提取 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 中有点麻烦,所以如果你需要在所有极端情况下都有效的相对时间,那么使用另一种语言可能会更好。


4
投票
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 拥有最简洁的方法。


3
投票

这就是答案吗?

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
[...]

0
投票

除了已经提到的有些日子有 23 小时,有些日子有 25 小时之外,这个问题还有一些模糊的成分。我们可以通过说“平均一天是 24 小时”来暂时修复该部分。

即便如此,我们也需要定义“一天”的含义。这里有 3 种可能性:

  1. 日历日 — 可能的问题是这样的:假设我们在 4 月 1 日中午
    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
  1. 平均日数 — 日龄的
    mtime
    至少为 12 小时前以及此后每 24 小时一次。 (伪代码)

number_days = round((now_in_secs - mtime_in_secs) / secs_per_average_day)

  1. 全天 — 日龄的
    mtime
    至少为 24 小时前以及此后每 24 小时一次。 (伪代码)

number_days = floor((now_in_secs - mtime_in_secs) / secs_per_average_day)

© www.soinside.com 2019 - 2024. All rights reserved.