操作系统:Linux 文件系统类型:ext3 首选解决方案:Bash(脚本/一行程序)、Ruby或Python

我有几个目录,其中有几个子目录和文件。我需要列出所有这些目录,其构造方式是将每个一级目录列在其中最新创建/修改文件的日期和时间旁边。

为了说明这一点,如果我接触一个文件或修改它的内容向下几级子目录,该时间戳应该显示在第一级目录名旁边。假设我有一个这样的目录:

./alfa/beta/gamma/example.txt

我修改了文件example.txt的内容,我需要在第一级目录alfa旁边以人类可读的形式显示时间,而不是epoch。我已经尝试了一些使用find, xargs, sort和类似的东西,但我不能绕过“alfa”的文件系统时间戳不改变的问题,当我创建/修改文件的几个级别。


当前回答

GNU find(参见man find)有一个-printf参数,用于在Epoch mtime和相对路径名中显示文件。

redhat> find . -type f -printf '%T@ %P\n' | sort -n | awk '{print $2}'

其他回答

忽略隐藏文件-良好和快速的时间戳

下面介绍如何查找并列出带有子目录的目录中最新修改的文件。隐藏文件被故意忽略。然而文件名中的空格处理得很好-不是说你应该使用它们!时间格式可以自定义。

$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10

2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht
2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht
2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht
2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht

更多的发现可以通过以下链接找到。

这篇文章中的Perl和Python解决方案帮助我解决了Mac OS X上的这个问题:

如何递归地列出按修改日期排序的文件(没有可用的stat命令!)

引自帖子:

Perl:

find . -type f -print |
perl -l -ne '
    $_{$_} = -M;  # store file age (mtime - now)
    END {
        $,="\n";
        print sort {$_{$b} <=> $_{$a}} keys %_;  # print by decreasing age
    }'

Python:

find . -type f -print |
python -c 'import os, sys; times = {}
for f in sys.stdin.readlines(): f = f[0:-1]; times[f] = os.stat(f).st_mtime
for f in sorted(times.iterkeys(), key=lambda f:times[f]): print f'

试试这个:

#!/bin/bash
find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head

在执行它时,使用它应该开始递归扫描的目录的路径(它支持带空格的文件名)。

如果有很多文件,它可能需要一段时间才能返回任何东西。如果我们使用xargs来代替,性能可以得到改善:

#!/bin/bash
find $1 -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head

这样会快一点。

您可以尝试查找的printf ACTION

%Ak文件最后一次访问时间 由k指定的格式, 它要么是@',要么是C strftime的指令 函数。列出了k的可能值 下面的; 其中一些可能无法全部使用 系统中,由于 到系统之间' strftime'的差异。

详情请参见@anubhava的回答

@anubhava的回答很好,但不幸的是,它不能在BSD工具上工作——也就是说,它不能与macOS上默认安装的find一起工作,因为BSD find没有-printf操作符。

所以这里有一个变体,适用于macOS + BSD(在我的Catalina Mac上测试),它结合了BSD find与xargs和stat:

$ find . -type f -print0 \
      | xargs -0 -n1 -I{} stat -f '%Fm %N' "{}" \
      | sort -rn 

当我在这里时,这里是我喜欢使用的BSD命令序列,它将时间戳设置为ISO-8601格式

$ find . -type f -print0 \
    | xargs -0 -n1 -I{} \
       stat  -f '%Sm %N' -t '%Y-%m-%d %H:%M:%S' "{}" \
    | sort -rn

(注意,与@anubhava的答案不同,我的答案将文件名从find传递给xargs作为单个参数,而不是以\0终止的列表,这将改变在最后输出的内容)

下面是GNU版本(即@anubhava的答案,但是iso-8601格式):

$ gfind . -type f -printf "%T+ %p\0" | sort -zk1nr

相关问:查找缺少选项-printf,现在怎么办?