如何递归查找目录中的最新修改文件?

JMW*_*JMW 233 filesystems bash find

ls在执行递归调用时,似乎没有正确排序文件:

ls -altR . | head -n 3
Run Code Online (Sandbox Code Playgroud)

如何在目录(包括子目录)中找到最近修改过的文件?

plu*_*dra 344

find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "
Run Code Online (Sandbox Code Playgroud)

对于一棵巨大的树,可能很难sort将所有东西都留在记忆中.

%T@为您提供修改时间,如unix时间戳,以sort -n数字方式排序,tail -1取最后一行(最高时间戳),cut -f2 -d" "从输出中删除第一个字段(时间戳).

编辑:就像-printf可能只有GNU一样,ajreals的使用stat -c也是如此.虽然可以在BSD上执行相同的操作,但格式化的选项是不同的(-f "%m %N"看起来似乎)

我错过了复数的部分; 如果你想要更多最新文件,只需提高尾部参数.

  • 如果订单很重要,您可以切换使用`sort -rn | 头-3`而不是`sort -n | 尾巴-3` 一个版本提供从最旧到最新的文件,而另一个版本从最新到最旧. (5认同)
  • 我有一个巨大的目录(大约一万个小文件),我担心性能,但是...这个命令运行不到一秒钟!太好了,非常感谢!!! :-) (3认同)
  • 我发现以下内容更短且具有更多可解释的输出:`find 。-type f -printf '%TF %TT %p\n' | 排序 | 尾-1` (3认同)
  • "对于一棵巨大的树,可能很难将所有东西都留在记忆中." `sort`将根据需要创建临时文件(在`/ tmp`中),所以我不认为这是一个问题. (2认同)
  • 如果您知道文件最后一次更改是在过去一周内,则可以将选项“-mtime -7”添加到“查找”以大大加快进程。 (2认同)

Eme*_*gia 124

关注@ plundra的回答,这是BSD和OS X版本:

find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "
Run Code Online (Sandbox Code Playgroud)

  • 最好使用`find ... -print0 | xargs -0 stat ...`而不是`find -exec stat ... {} \;` - 后者为每个文件启动一个`stat`进程,但前者对许多文件使用一个`stat`进程.另外,`sort -n | tail -1`浪费时间在`tail`中丢弃输出:更好地写`sort -rn | head -1`这样只需要处理`sort`的一行输出.我相应地更新了答案. (4认同)
  • 已经提出了答案,但只是一个upvote不会做.不得不为此感谢你!帮助我很大 (3认同)

mar*_*rco 17

您可以使用awk仅打印具有最大修改时间(在unix时间内)的结果,而不是对结果进行排序并仅保留最后修改的结果:

find . -type f -printf "%T@\0%p\0" | awk '
    {
        if ($0>max) {
            max=$0; 
            getline mostrecent
        } else 
            getline
    } 
    END{print mostrecent}' RS='\0'
Run Code Online (Sandbox Code Playgroud)

如果文件数量足够大,这应该是解决问题的更快方法.

我使用了NUL字符(即'\ 0'),因为理论上,文件名可能包含任何字符(包括空格和换行符)但是.

如果您的系统中没有这样的病态文件名,您也可以使用换行符:

find . -type f -printf "%T@\n%p\n" | awk '
    {
        if ($0>max) {
            max=$0; 
            getline mostrecent
        } else 
            getline
    } 
    END{print mostrecent}' RS='\n'
Run Code Online (Sandbox Code Playgroud)

另外,这也适用于mawk.


Flo*_*aus 10

我在Solaris 10下找到最后修改过的文件时遇到了麻烦.find没有printf选项,stat也没有.我发现以下解决方案对我有用:

find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1
Run Code Online (Sandbox Code Playgroud)

要显示文件名以及使用

find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1
Run Code Online (Sandbox Code Playgroud)

说明

  • find . -type f 查找并列出所有文件
  • sed 's/.*/"&"/' 将路径名包装在引号中以处理空格
  • xargs ls -E发送引用的路径ls,该-E选项确保返回完整的时间戳(格式年 - 月 - 日小时 - 分 - 秒 - 纳秒)
  • awk '{ print $6," ",$7 }' 仅提取日期和时间
  • awk '{ print $6," ",$7," ",$9 }' 提取日期,时间和文件名
  • sort 返回按日期排序的文件
  • tail -1 仅返回上次修改的文件


小智 9

这似乎工作正常,即使对于子目录:

find . -type f | xargs ls -ltr | tail -n 1
Run Code Online (Sandbox Code Playgroud)

如果文件太多,请优化查找.

  • 这似乎按目录排序,因此它不一定会显示最新的文件 (6认同)
  • 如果文件路径中有空格,最好执行:`find . -type f -print0 | xargs -0 ls -ltr | xargs -0 ls -ltr | xargs -0 ls -ltr | xargs -0 ls -ltr 尾部-n 1` (2认同)

Pie*_*e D 7

我一直使用类似的东西,以及最近修改过的文件的前 k 列表。对于大型目录树,避免排序快得多。在只有 top-1 最近修改的文件的情况下:

find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'
Run Code Online (Sandbox Code Playgroud)

在包含 170 万个文件的目录中,我在 3.4 秒内获得了最新的一个,与使用排序的 25.5 秒解决方案相比,速度提高了 7.5 倍。


Fab*_*ler 6

显示具有人类可读时间戳的最新文件:

find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1
Run Code Online (Sandbox Code Playgroud)

结果如下所示:

2015-10-06 11:30: +0200 ./foo/bar.txt
Run Code Online (Sandbox Code Playgroud)

要显示更多文件,请-n1使用更高的数字替换


Ser*_*ndt 6

使用find\xe2\x80\x94 和漂亮且快速的时间戳

\n

以下是如何在具有子目录的目录中查找并列出最新修改的文​​件。隐藏文件被故意忽略。时间格式可以自定义。

\n
$ find . -type f -not -path \'*/\\.*\' -printf \'%TY-%Tm-%Td %TH:%TM %Ta %p\\n\' |sort -nr |head -n 10\n
Run Code Online (Sandbox Code Playgroud)\n

结果

\n

很好地处理文件名中的空格 \xe2\x80\x94 不应该使用这些!

\n
2017-01-25 18:23 Wed ./indenting/Shifting blocks visually.mht\n2016-12-11 12:33 Sun ./tabs/Converting tabs to spaces.mht\n2016-12-02 01:46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht\n2016-11-09 17:05 Wed ./Word count - Vim Tips Wiki.mht\n
Run Code Online (Sandbox Code Playgroud)\n

更多的

\n

更多 find内容请点击链接。

\n


Kar*_*rlo 5

这给出了一个排序列表:

find . -type f -ls 2>/dev/null | sort -M -k8,10 | head -n5
Run Code Online (Sandbox Code Playgroud)

通过在排序命令中放置“-r”来反转顺序。如果您只需要文件名,请插入“awk '{print $11}' |” 在'|之前 头'