我正在使用 bash 构建一个脚本,在其中我将在变量中获取文件名,然后使用此变量获取文件 unix 上次修改日期。
我需要得到这个修改日期值,我不能使用 stat 命令。
你知道用常用的 *nix 命令获取它的任何方法吗?
ls
:解析ls
是个坏主意。不仅文件名中某些字符的行为未定义且取决于平台,而且出于您的目的,它会与过去六个月的日期混淆。简而言之,是的,它可能会在您有限的测试中为您工作。它不是独立于平台的(因此没有可移植性),并且鉴于各种系统上的“合法”文件名范围,无法保证您的解析行为。(例如,Ext4允许文件名中有空格和换行符)。
说了这么多,就个人而言,我会使用它,ls
因为它既快速又简单;)
正如雨果在评论中指出的那样,OP 不想使用stat
. 此外,我应该指出,以下部分是 BSD-stat 特定的(%Sm
当我在 Ubuntu 上测试时,该标志不起作用;Linux 有一个stat
命令,如果您对它感兴趣,请阅读手册页)。
stat
解决方案:使用日期date
,至少在 Linux 上,有一个标志:-r
,根据手册页:
显示FILE的最后修改时间
因此,脚本化解决方案将与此类似:
date -r ${MY_FILE_VARIABLE}
这会给你返回类似的东西:
zsh% date -r MyFile.foo
Thu Feb 23 07:41:27 CST 2012
要解决 OP 的评论:
如果可能,使用可配置的日期格式
date
有一组相当广泛的时间格式变量;阅读手册页以获取更多信息。
我不能 100% 确定date
所有“类 UNIX 系统”的可移植性。对于基于 BSD 的(例如 OS X),这是行不通的;BSD-date的-r
标志做了完全不同的事情。这个问题并没有具体说明解决方案的便携性。对于基于 BSD 的解决方案,请参阅以下部分;)
使用stat
. stat
您可以使用标志格式化输出-f
,并且可以选择仅显示文件修改数据(对于这个问题,这很好)。
例如stat -f "%m%t%Sm %N" ./*
:
1340738054 Jun 26 21:14:14 2012 ./build
1340738921 Jun 26 21:28:41 2012 ./build.xml
1340738140 Jun 26 21:15:40 2012 ./lib
1340657124 Jun 25 22:45:24 2012 ./tests
其中第一位是UNIX 纪元时间,日期是文件修改时间,其余的是文件名。
示例命令的细分
stat -f "%m%t%Sm %N" ./*
stat -f
:调用stat
,并指定格式(-f
)。%m
: UNIX 纪元时间。%t
:输出中的制表符分隔符。%Sm
:S
表示将输出显示为string
,m
表示使用文件修改数据。%N
:显示相关文件的名称。脚本中的命令如下所示:
stat -f "%Sm" ${FILE_VARIABLE}
将为您提供输出,例如:
Jun 26 21:28:41 2012
有perl吗?
perl -MFile::stat -e "print scalar localtime stat('FileName.txt')->mtime"
怎么样:
find $PATH -maxdepth 1 -name $FILE -printf %Tc
有关可以与 %T 一起使用的其他值,请参见 find 手册页。
您可以使用“日期”命令添加所需的格式选项格式:
date +%Y-%m-%d -r /root/foo.txt
2013-05-27
date +%H:%M -r /root/foo.txt
23:02
您可以使用ls -l
which列出最后修改时间,然后使用cut
删除修改日期:
mod_date=$(ls -l $file_name | cut -c35-46)
这适用于我的系统,因为日期出现在第 35 到 46 列之间。您可能必须在系统上使用它。
日期有两种不同的格式:
Mmm dd hh:mm
Mmm dd yyyy
一年多前修改的文件将采用后一种格式。不到一年前修改的文件必须先格式化。您可以搜索“:”并知道文件的格式:
if echo "$mod_date" | grep -q ":"
then
echo "File was modified within the year"
else
echo "File was modified more than a year ago"
fi