Unix命令('stat'和'ls'除外)无需解析即可获取文件修改日期

Posted

技术标签:

【中文标题】Unix命令(\'stat\'和\'ls\'除外)无需解析即可获取文件修改日期【英文标题】:Unix command (other than 'stat' and 'ls') to get file modification date without parsingUnix命令('stat'和'ls'除外)无需解析即可获取文件修改日期 【发布时间】:2012-06-28 06:54:47 【问题描述】:

我正在编写一个 shell 脚本,我必须在其中找到文件的最后修改日期。

Stat 命令在我的环境中不可用。

所以我如下使用'ls' 来获得所需的结果。

ls -l filename | awk 'print $6 $7 $8'

但是我在很多论坛上读到过parsing ls is generally considered bad practise。虽然它(可能)大部分时间都能正常工作,但不能保证每次都能正常工作。

有没有其他方法可以在 shell 脚本中获取文件修改日期。

【问题讨论】:

【参考方案1】:

使用find 命令怎么样?

例如,

 $ find filenname -maxdepth 0 -printf "%TY-%Tm-%Td %TH:%TM\n"

这个特殊的格式字符串给出如下输出:2012-06-13 00:05

find man page 显示了您可以与printf 一起使用的格式化指令,以根据您的需要/想要调整输出。 -printf format 部分包含所有详细信息。

ls 输出与find 进行比较:

$ ls -l uname.txt | awk 'print  $6 , "", $7'
2012-06-13  00:05

$ find uname.txt -maxdepth 0 -printf "%TY-%Tm-%Td %TH:%TM\n"
2012-06-13 00:05

当然,您可以使用 Python 或 Perl 等多种语言编写脚本,以获得相同的信息,但是要求“unix 命令”听起来好像您正在寻找一个“内置”shell 命令。

编辑

您也可以像这样从命令行中调用 Python:

$ python -c "import os,time; print time.ctime(os.path.getmtime('uname.txt'))"

或者如果与其他 shell 命令结合使用:

$ echo 'uname.txt' | xargs python -c "import os,time,sys; print time.ctime(os.path.getmtime(sys.argv[1]))"

都返回:Wed Jun 13 00:05:29 2012

【讨论】:

如果stat 不可用,很有可能find -printf 选项也不可用。 stat 不是标准的 Unix 命令,而 -printf 是 Gnu 扩展。 @jlliagre 很好,希望 OP 会让我们知道这是否是一个可行的解决方案。如果没有,我们可以考虑其他选择。 OSX (10.9):我们有 stat 但没有 printf。【参考方案2】:

根据您的操作系统,您可以使用

date -r FILENAME

唯一似乎无法在 Mac OS 上运行的 unix 版本,根据 man 文件,-r 选项是:

 -r seconds
         Print the date and time represented by seconds, where seconds is
         the number of seconds since the Epoch (00:00:00 UTC, January 1,
         1970; see time(3)), and can be specified in decimal, octal, or
         hex.

而不是

   -r, --reference=FILE
          display the last modification time of FILE

【讨论】:

date -r 在 OS X 上不可用 :(【参考方案3】:

你有 perl 吗?

如果是这样,您可以使用其内置的stat 函数来获取有关命名文件的 mtime(和其他信息)。

这是一个小脚本,它获取文件列表并打印每个文件的修改时间:

#!/usr/bin/perl

use strict;
use warnings;

foreach my $file (@ARGV) 
    my @stat = stat $file;
    if (@stat) 
        print scalar localtime $stat[9], " $file\n";
    
    else 
        warn "$file: $!\n";
    

样本输出:

$ ./mtime.pl ./mtime.pl nosuchfile
Tue Jun 26 14:58:17 2012 ./mtime.pl
nosuchfile: No such file or directory

File::stat 模块用更用户友好的版本覆盖了stat 调用:

#!/usr/bin/perl

use strict;
use warnings;

use File::stat;

foreach my $file (@ARGV) 
    my $stat = stat $file;
    if ($stat) 
        print scalar localtime $stat->mtime, " $file\n";
    
    else 
        warn "$file: $!\n";
    

【讨论】:

【参考方案4】:
#!/bin/bash 
FILE=./somefile.txt

modified_at=`perl -e '$x = (stat("'$FILE'"))[9]; print "$x\n";'`

not_changed_since=`perl -e '$x = time - (stat("'$FILE'"))[9]; print "$x\n";'`

echo "Modified at $modified_at"
echo "Not changed since $not_changed_since seconds"

【讨论】:

以上是关于Unix命令('stat'和'ls'除外)无需解析即可获取文件修改日期的主要内容,如果未能解决你的问题,请参考以下文章

UNIX环境高级编程--4

关于Linux的SUID位!

stat命令

Linux查看文件大小的几种方法示例 stat du ls awk (转)

Linux查看文件大小的几种方法示例 stat du ls awk (转)

请问,unix中ls命令如何显示文件以GB为单位的大小