在Bash中打印文件的最后修改日期

210

我似乎找不到如何打印文件日期的方法。我已经能够列出目录中的所有文件,但我需要同时打印出它们的日期。

我知道需要将一个日期格式附加到条目的输出中,但我无法找到正确的格式。

echo "Please type in the directory you want all the files to be listed"

read directory 

for entry in "$directory"/*
do
  echo "$entry"
done

2
请键入您想要列出所有文件的目录:read -p“” directory - CousinCocaine
10个回答

339

'date' 命令不是更简单吗?无需使用 awk、stat 等。

date -r <filename>

另外,考虑查看日期格式化的man页面;例如常见的日期和时间格式:

date -r <filename> "+%m-%d-%Y %H:%M:%S"

16
比使用stat更简单/更易得到。 - Ingmar Boddington
12
看起来BSD(或至少是OS X的)的date命令没有这个功能。它的-r选项只是用于提供一个时间戳进行格式化。你需要使用GNU date命令才能获得这个功能。 - Waleed Khan
4
在Mac OSX上使用以下命令:date stat -f "%Sm" -t "%m%d%H%M%y" "${1}" - Michaelangel007
3
在OS X 10.10上,使用“date -r <文件名>”命令可以正常工作,尽管man文档没有描述任何<文件名>参数。 - gotofritz
4
在 macOS 10.13 中,date [-r seconds | filename] 已经有完整的 man 页面文档,并且按照预期工作。 - Echelon
显示剩余8条评论

168
你可以使用stat 命令。
stat -c %y "$entry"

更多信息

%y 最后修改时间,以易于阅读的方式呈现

在终端中无法正常工作。会打印出“stat: missing operand” - Hokerie
嗯,可能是我的Ubuntu系统问题吗?你知道使用stat命令的要求是什么吗? - Hokerie
40
请注意,在Mac OS X上,使用命令stat -f "%m%t%Sm %N" filename(有关更多详细信息,请参见man stat示例部分)来查看文件的修改时间和名称。 - Olie
3
请注意,在BSD系统中,stat命令的语法不同。在FreeBSD中使用以下语法:stat -f %Sm -t %F" "%R 文件名 - Sopalajo de Arrierez

31

或者,你也可以尝试:

date -r filename +"%Y-%m-%d %H:%M:%S"

这个答案是 https://dev59.com/S2Qo5IYBdhLWcg3wBLco#20807343 的重复。 - Ulysse BN
6
不,它略有不同。他主张使用更好的日期格式。 - iconoclast

16
在OS X上,我喜欢我的日期格式为YYYY-MM-DD HH:MM,以便在文件输出中显示。
因此,要指定一个文件,我会使用:
stat -f "%Sm" -t "%Y-%m-%d %H:%M" [filename]

如果我想在一系列文件上运行它,我可以像这样做:
#!/usr/bin/env bash
for i in /var/log/*.out; do
  stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i"
done

这个例子将打印出我上次运行sudo periodic daily weekly monthly命令的时间,因为它引用了日志文件。


如果要在每个日期下添加文件名,可以运行以下命令:

#!/usr/bin/env bash
for i in /var/log/*.out; do
  stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i"
  echo "$i"
done

输出结果如下:
2016-40-01 16:40
/var/log/daily.out
2016-40-01 16:40
/var/log/monthly.out
2016-40-01 16:40
/var/log/weekly.out

很遗憾,我不知道如何防止换行并在日期后附加文件名,而不添加更多脚本行。


PS - 我使用 #!/usr/bin/env bash,因为我是一名白天使用Python的用户,并且在系统上安装了不同版本的而非#!/bin/bash


如果您还没有弄清楚换行部分,那么echo程序可以使用-e标志。例如用法可能是:echo -e "$(stat -f %Sm -t %Y%m%d_%H%M%S $AFile)\t$AFile."。在您的情况下,它可能是:echo -e "$(stat -f "%Sm" -t "%Y-%m-%d %H:%M" "$i")\t$i." - Thoth

7

补充@StevePenny的答案,你可能想删掉不太易读的部分:

stat -c%y Localizable.strings | cut -d'.' -f1

4

关于换行,我编辑了您的代码,得到了一个没有换行的结果。

#!/bin/bash
for i in /Users/anthonykiggundu/Sites/rku-it/*; do
   t=$(stat -f "%Sm"  -t "%Y-%m-%d %H:%M" "$i")
   echo $t : "${i##*/}"  # t only contains date last modified, then only filename 'grokked'- else $i alone is abs. path           
done

3
如果文件名没有空格:
ls -l <dir> | awk '{print $6, " ", $7, " ", $8, " ", $9 }'

这会打印出如下格式:

 Dec   21   20:03   a1.out
 Dec   21   20:04   a.cpp

如果文件名中有空格(对于没有空格的文件名,您也可以使用以下命令,只是它看起来比前者更复杂/丑陋):
 ls -l <dir> | awk '{printf ("%s %s %s ",  $6,  $7, $8); for (i=9;   i<=NF; i++){ printf ("%s ", $i)}; printf ("\n")}'

啊,我明白了!那基本上是可以的,除了文件名中有空格的情况。有解决方法吗? - Hokerie
实际上,我又试了一遍,还是不行...原来我试的是一个没有空格文件名的目录。=/ 我已经在下面编辑了我的答案。 - Hokerie
当你说它不起作用时,能否说一下错误是什么?我在我的系统上执行时它可以工作。 - Bill
我得到了一个“没有这个文件或目录”的错误。 - Hokerie
这是因为您传递了一个不存在的值 <dir> ... 代码完全没有问题。 - Bill

2

编辑:事实证明,我忘记了$entry所需的引号,以便正确打印并不会出现“没有此文件或目录”的错误。非常感谢大家的帮助!

这是我的最终代码:

    echo "Please type in the directory you want all the files to be listed with last modified dates" #bash can't find file creation dates

read directory

for entry in "$directory"/*

do
modDate=$(stat -c %y "$entry") #%y = last modified. Qoutes are needed otherwise spaces in file name with give error of "no such file"
modDate=${modDate%% *} #%% takes off everything off the string after the date to make it look pretty
echo $entry:$modDate

打印出来的样子如下:
/home/joanne/Dropbox/cheat sheet.docx:2012-03-14
/home/joanne/Dropbox/Comp:2013-05-05
/home/joanne/Dropbox/Comp 150 java.zip:2013-02-11
/home/joanne/Dropbox/Comp 151 Java 2.zip:2013-02-11
/home/joanne/Dropbox/Comp 162 Assembly Language.zip:2013-02-11
/home/joanne/Dropbox/Comp 262 Comp Architecture.zip:2012-12-12
/home/joanne/Dropbox/Comp 345 Image Processing.zip:2013-02-11
/home/joanne/Dropbox/Comp 362 Operating Systems:2013-05-05
/home/joanne/Dropbox/Comp 447 Societal Issues.zip:2013-02-11

2

我想以 YYYYMMDDHHMMSS 格式获取文件的修改日期。以下是我的方法:

date -d @$( stat -c %Y myfile.css ) +%Y%m%d%H%M%S

解释。 这是这些命令的组合:

stat -c %Y myfile.css # Get the modification date as a timestamp
date -d @1503989421 +%Y%m%d%H%M%S # Convert the date (from timestamp)

-2

您可以使用:

ls -lrt filename |awk '{printf "%02d",$7}'

这将以两位数字显示日期(一个当前月份的日期)。

如果在19之间,它会添加“0”前缀并转换为01-09。

希望这符合您的期望。


解析 ls 输出是一种反模式。 - Tripp Kinetics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接