按修改日期查找最新文件

如果我想在包含子目录的(大)目录中找到最新文件(mtime),我该怎么办?

我发现的很多post都暗示了ls -lt | head一些变化 ls -lt | head (有趣的是,很多人建议ls -ltr | tail是相同但效率较低的),除非你有子目录(我这样做),这很好。

然后,你可以

 find . -type f -exec ls -lt \{\} \+ | head 

这肯定会对一个命令指定的文件数量有所帮助,即如果你有一个目录, -exec...\+将发出单独的命令; 因此,每个组本身将按ls排序,但不会超过总集合; 因此,负责人将获得第一批最新的条目。

任何答案?

您不需要重复使用外部命令(如ls ),因为find可以通过-printf操作完成所有操作:

 find /path -printf '%T+ %p\n' | sort -r | head 

我今天遇到了类似的问题,但我没有find攻击了它。 我需要一些简短的东西,我可以在ssh上运行,以返回我的主目录中最近编辑的文件。 这大致是我提出的:

 ls -tp | grep -v /$ | head -1 

ls-p选项向目录添加尾部斜杠, grep -v删除以斜杠(也称为所有目录)结尾的行, head -1将输出限制为单个文件。

如果你想要返回的只是文件名,那么这比使用find要简单得多。

这比我在printf上的系统更快,但我不明白为什么

 find /path -type f -exec stat -c "%y %n" {} + | sort -r | head 

它不是那么时髦,但也可以通过Midnight Commander实现这一点:搜索*,将结果镶板,按相反的顺序按修改时间排序。

显然,它比find快一点 – 我的主目录,包含922000个文件,在几乎14分钟内按mc排序,而find花费少于5个 – 但有一些好处:

  • 我可能会花费更长的时间然后发现一个正确的查找调用的9分钟差异:)

  • 减少错误的机会(忘记指定-r进行排序等 – 再次启动)

  • 可以通过更改排序顺序等来使用结果集 – 无需重新查询文件。

  • 可以仅对结果集中的某些文件执行文件操作 – 即按大小排序,删除一些不需要的大文件

编辑:我想这篇文章并不像我想象的那样“不是特别有用”。 这是一个非常快速的解决方案,只是跟踪最近修改的文件(而不是排序整个文件列表):

find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '

为清晰起见,分布在多行上,如下所示:

 find . -type f -printf '%T@ %p\n' | awk ' BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' ' 

编辑结束


不是特别有用的post,但由于’安排’正在讨论速度,我想我会分享这个。

arrange和enzotib的解决方案包括用mtimes列出目录中的所有文件然后排序。 如您所知,排序不是必需的,以找到最大值。 查找最大值可以在线性时间内完成,但排序需要n log(n)时间[我知道差异不大,但仍然;)]。 我想不出一个实现这个的巧妙方法。 [编辑:上面提供的整洁(虽然看起来很脏)和快速实施。]

下一个最好的事情 – 要在目录中查找最近编辑的文件,递归查找每个1级子目录中最近编辑的文件。 让这个文件代表子目录。 现在将1级文件与1级子目录的代表一起排序。 如果每个目录的1级文件和子目录的数量几乎是一个常数,那么这个过程应该与文件总数成线性比例。

这是我想出来实现这个:

 findrecent() { { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; } findrecent . 

我跑了这个并得到了一堆find: findrecent: No such file or directory错误。 原因:-exec的find在不同的shell中运行。 我尝试在.bashrc,.xsessionrc中定义findrecent,但这些没有帮助[我在此感谢帮助]。 最后我采取了推杆

 #!/bin/bash { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; 

在我的PATH中名为findrecent的脚本中然后运行它。

我跑了这个,一直等着没有输出。 只是为了确保我没有处理我修改文件的任何无限循环

 #!/bin/bash echo "$1" >&2 { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; 

并再次尝试。 它确实有效 – 但在我的家庭文件夹上花了1分35秒 – 安排和enzotib的解决方案分别花了1.69,1.95秒!

O(n)优于O(n log(n))的优势! 该死的函数调用开销! [或者说脚本调用开销]

但是这个脚本确实比早期的解决方案更好地扩展,我敢打赌它在谷歌的内存库上运行得比他们快; D

使用perl in conjonctin with find

  find my_directory -type f -printf '%T@\t%p\n' | perl -ane '@m=@F if ($F[0]>$m[0]); END{print $m[1];}' 

您将获得具有最大epoch == last文件修改的文件的名称。