如何递归查找并列出具有子目录和时间的目录中最新修改的文件
操作系统:Linux
文件系统类型:ext3
首选解决方案:Bash (script/one-liner)、Ruby、或Python
我有几个目录,其中有几个子目录和文件。我需要列出所有这些目录的列表,该列表的构造方式使得每个一级目录都列在其中最新创建/修改的文件的日期和时间旁边。
为了澄清这一点,如果我触摸一个文件或修改其内容的几个子目录级别,该时间戳应该显示在第一级目录名称旁边。假设我有一个如下结构的目录:
./alfa/beta/gamma/example.txt
并且我修改了文件 example.txt
的内容,我需要在 human 中将时间显示在第一级目录 alfa
旁边可读形式,而不是纪元。我尝试使用 find, xargs
, sort
之类的,但我无法解决这个问题'alfa' 的文件系统时间戳当我创建/修改几个级别的文件时,它不会改变。
Operating system: Linux
Filesystem type: ext3
Preferred solution: Bash (script/one-liner), Ruby, or Python
I have several directories with several subdirectories and files in them. I need to make a list of all these directories that is constructed in a way such that every first-level directory is listed next to the date and time of the latest created/modified file within it.
To clarify, if I touch a file or modify its contents a few subdirectory levels down, that timestamp should be displayed next to the first-level directory name. Say I have a directory structured like this:
./alfa/beta/gamma/example.txt
and I modify the contents of the file example.txt
, I need that time displayed next to the first-level directory alfa
in human readable form, not epoch. I've tried some things using find, xargs
, sort
and the like, but I can't get around the problem that the filesystem timestamp of 'alfa' doesn't change when I create/modify files a few levels down.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(22)
我使用这个,你可以使用 grep 和 regexp ie
在 mac 上,如果你想过滤一些文件,
On mac I use this
if you want filter some files you can use grep with regexp i.e.
你可以尝试一下 find 的 printf ACTION
请在 @anubhava 的回答中查找详细信息
You may give the printf ACTION of find a try
Please find the details in @anubhava's answer
试试这个:
使用应该开始递归扫描的目录路径来执行它(它支持带空格的文件名)。
如果有很多文件,可能需要一段时间才能返回任何内容。如果我们使用 xargs 来代替,则可以提高性能:速度
更快一些。
Try this one:
Execute it with the path to the directory where it should start scanning recursively (it supports filenames with spaces).
If there are lots of files it may take a while before it returns anything. Performance can be improved if we use
xargs
instead:which is a bit faster.
要查找文件状态上次更改于 N 分钟前的所有文件:
例如:
使用
-ctime
而不是-cmin
天数:在 FreeBSD 和 MacOS 上:您还可以使用
-ctime n[smhdw]
表示秒、分钟、小时、天和周。如果未提供单位,则默认为天。示例:
To find all files whose file status was last changed N minutes ago:
For example:
Use
-ctime
instead of-cmin
for days:On FreeBSD and MacOS: You can also use
-ctime n[smhdw]
for seconds, minutes, hours, days, and weeks. Days is the default if no unit is provided.Examples:
GNU find(参见
man find
)有一个-printf
参数,用于显示Epoch mtime和相对路径名中的文件。GNU find (see
man find
) has a-printf
parameter for displaying the files in Epoch mtime and relative path name.我缩短了 Daniel Böhmer 对这句话的精彩回答:
如果文件名中有空格,您可以使用此修改:
I shortened Daniel Böhmer's awesome answer to this one-liner:
If there are spaces in filenames, you can use this modification:
试试这个:
它使用
find
收集所有文件从目录中,ls
按修改日期排序列出它们,< code>head 用于选择第一个文件,最后stat
以良好的格式显示时间。目前,名称中含有空格或其他特殊字符的文件并不安全。如果还不能满足您的需求,请写一篇推荐。
Try this:
It uses
find
to gather all files from the directory,ls
to list them sorted by modification date,head
for selecting the first file and finallystat
to show the time in a nice format.At this time it is not safe for files with whitespace or other special characters in their names. Write a commend if it doesn't meet your needs yet.
这就是我正在使用的(非常高效):
优点:
用法:
其中:
dir
-要搜索的目录 [当前目录]number
- 要显示的最新文件的数量 [10]find_last /etc 4
的输出如下所示:This is what I'm using (very efficient):
PROS:
USAGE:
where:
dir
- a directory to be searched [current dir]number
- number of newest files to display [10]Output for
find_last /etc 4
looks like this:此命令适用于 Mac OS X:
find "$1" -type f -print0 | xargs -0 gstat --format '%Y :%y %n' | xargs -0 gstat --format '%Y :%y %n' |排序-nr |剪切-d:-f2- | head
在 Linux 上,正如原始发布者所要求的那样,使用
stat
而不是gstat
。这个答案当然是 user37078 的出色解决方案,从评论提升为完整答案。我融入了 CharlesB 的见解,在 Mac OS X 上使用
gstat
。我从 MacPorts 而不是 自制程序。以下是我如何将其打包到一个简单的命令
~/bin/ls-recent.sh
中以供重用:This command works on Mac OS X:
find "$1" -type f -print0 | xargs -0 gstat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head
On Linux, as the original poster asked, use
stat
instead ofgstat
.This answer is, of course, user37078's outstanding solution, promoted from comment to full answer. I mixed in CharlesB's insight to use
gstat
on Mac OS X. I got coreutils from MacPorts rather than Homebrew, by the way.And here's how I packaged this into a simple command
~/bin/ls-recent.sh
for reuse:忽略隐藏文件——使用nice &快速时间戳
下面介绍如何在具有子目录的目录中查找并列出最新修改的文件。隐藏文件被故意忽略。尽管文件名中的空格处理得很好,但并不是说您应该使用它们!时间格式可以自定义。
更多
find
丰富可以通过以下链接找到。Ignoring hidden files — with nice & fast time stamp
Here is how to find and list the latest modified files in a directory with subdirectories. Hidden files are ignored on purpose. Whereas spaces in filenames are handled well — not that you should use those! The time format can be customised.
More
find
galore can be found by following the link.这篇文章中的 Perl 和 Python 解决方案都帮助我在 Mac OS X 上解决了这个问题:
如何递归地列出按修改日期排序的文件(没有可用的 stat 命令!)
引用帖子:
Perl:
Python :
Both the Perl and Python solutions in this post helped me solve this problem on Mac OS X:
How to list files sorted by modification date recursively (no stat command available!)
Quoting from the post:
Perl:
Python:
以下是一个适用于可能包含空格、换行符和全局字符的文件名的版本:
find ... -printf
打印文件修改时间 (纪元值)后跟一个空格和以\0
结尾的文件名。sort -zk1nr
读取 NUL 终止数据并按数字反向排序由于问题是用 Linux 标记的,我假设 GNU 核心实用程序可用。
您可以使用上面的管道:
打印修改时间和按修改时间排序的文件名(最近的在前),以换行符结尾。
Here is one version that works with filenames that may contain spaces, newlines, and glob characters as well:
find ... -printf
prints the file modification time (Epoch value) followed by a space and\0
terminated filenames.sort -zk1nr
reads NUL terminated data and sorts it reverse numericallyAs the question is tagged with Linux, I am assuming GNU Core Utilities are available.
You can pipe the above with:
to print the modification time and filenames sorted by modification time (most recent first) terminated by newlines.
我显示的是最新访问时间,您可以轻松修改它以执行最新修改时间。
有两种方法可以做到这一点:
如果您想避免全局排序,如果您有数千万个文件,那么全局排序的成本可能会很高,那么您可以这样做(将自己定位在您希望搜索的目录的根目录中)开始):
<前><代码>Linux> touch -d @0 /tmp/a;
Linux>寻找 。 -type f -exec tcsh -f -c test `stat --printf="%X" {}` -gt `stat --printf="%X" /tmp/a` ; -exec tcsh -f -c touch -a -r {} /tmp/a ; -打印
上述方法打印访问时间逐渐更新的文件名,最后打印的文件是访问时间最新的文件。显然,您可以使用“tail -1”获取最新的访问时间。
您可以递归打印子目录中所有文件的名称和访问时间,然后根据访问时间和尾部最大条目进行排序:
<前><代码>Linux> \寻找 。 -type f -exec stat --printf="%X %n\n" {} \; | \排序-n |尾部-1
就这样......
I'm showing this for the latest access time, and you can easily modify this to do latest modification time.
There are two ways to do this:
If you want to avoid global sorting which can be expensive if you have tens of millions of files, then you can do (position yourself in the root of the directory where you want your search to start):
The above method prints filenames with progressively newer access time and the last file it prints is the file with the latest access time. You can obviously get the latest access time using a "tail -1".
You can have find recursively print the name and access time of all files in your subdirectory and then sort based on access time and the tail the biggest entry:
And there you have it...
我的 .profile 中有一个我经常使用的别名:
所以它会执行您正在寻找的操作(例外情况是它不会遍历更改日期/时间多个级别) - 查找最新文件(*.log 和 *.trc)在本例中为文件);它还只查找最后一天修改的文件,然后按时间排序并通过 管道输出less:
PS:注意,我在某些服务器上没有 root,但总是有 sudo,所以你可能不需要那部分。
I have this alias in my .profile that I use quite often:
So it does what you are looking for (with exception it doesn't traverse change date/time multiple levels) - looks for latest files (*.log and *.trc files in this case); also it only finds files modified in the last day, and then sorts by time and pipes the output through less:
PS.: Notice I don't have root on some of the servers, but always have sudo, so you may not need that part.
遇到的人
对于那些在执行 Heppo 的答案 (
find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head
)请尝试用
-c
键替换--format
,最后调用将是:我在一些 Docker 容器中工作,其中
stat
无法使用--format
选项。For those, who faced
when executed the line from Heppo's answer (
find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head
)Please try the
-c
key to replace--format
and finally the call will be:That worked for me inside of some Docker containers, where
stat
was not able to use--format
option.这实际上应该执行OP指定的操作:
Bash中的One-liner:
给出如下输出:
这列出了每个一级目录,以及这些文件夹中最新文件的人类可读时间戳,即使它位于子文件夹中,按照要求
This should actually do what the OP specifies:
One-liner in Bash:
which gives output such as:
This lists each first-level directory with the human-readable timestamp of the latest file within those folders, even if it is in a subfolder, as requested in
@anubhava 的回答很棒,但不幸的是不适用于 BSD 工具 - 即它不适用于 macOS 默认安装的
find
,因为 BSDfind
没有-printf
运算符。因此,这里有一个适用于 macOS + BSD 的变体(在我的 Catalina Mac 上测试),它将 BSD
find
与 xargs 和stat
:当我在这里时,这是我喜欢使用的 BSD 命令序列,它将时间戳放入 ISO-8601 格式
(请注意,与 @anubhava 不同,我的两个答案都将文件名从
find
传递到xargs
作为\0
终止列表,这会改变最后通过管道输出的内容)这是 GNU 版本(即 @anubhava 的答案,但采用 iso-8601 格式):
单个参数而不是 : find 缺少选项 -printf,现在怎么办?
@anubhava's answer is great, but unfortunately won't work on BSD tools – i.e. it won't work with the
find
that comes installed by default on macOS, because BSDfind
doesn't have the-printf
operator.So here's a variation that works with macOS + BSD (tested on my Catalina Mac), which combines BSD
find
with xargs andstat
:While I'm here, here's BSD command sequence I like to use, which puts the timestamp in ISO-8601 format
(note that both my answers, unlike @anubhava's, pass the filenames from
find
toxargs
as a single argument rather than a\0
terminated list, which changes what gets piped out at the very end)And here's the GNU version (i.e. @anubhava's answer, but in iso-8601 format):
Related q: find lacks the option -printf, now what?
Bash 有一个单行脚本解决方案,用于解决如何在多个目录中递归查找最新修改的文件。请在您的目标目录中找到以下命令。
对于今天,grep 今天的日期或时间,如下面命令中所述
Bash has one-liner-script solution for, how to recursively find latest modified files in multiple directories. kindly find below command with your target directories.
and for today, grep today date or time as mentioned in below command
Quick Bash 功能:
查找目录中最新修改的文件:
您还可以指定自己的日期/时间格式作为第三个参数。
Quick Bash function:
Find the latest modified file in a directory:
You can also specify your own date/time format as the third argument.
以下内容返回时间戳字符串和具有最新时间戳的文件名:
产生以下形式的输出:<文件名>
<代码>
The following returns you a string of the timestamp and the name of the file with the most recent timestamp:
Resulting in an output of the form:
<yy-mm-dd-hh-mm-ss.nanosec> <filename>
对于纯
ls
输出,请使用它。没有参数列表,所以它不能太长:并用
cut
来优化日期、时间和名称:编辑:刚刚注意到当前最佳答案按修改日期排序。这与这里的第二个示例一样简单,因为修改日期是每行的第一个 - 在末尾进行排序:
For plain
ls
output, use this. There is no argument list, so it can't get too long:And niceified with
cut
for just the dates, times, and name:EDIT: Just noticed that the current top answer sorts by modification date. That's just as easy with the second example here, since the modification date is first on each line - slap a sort onto the end:
这也可以通过 Bash 中的递归函数来完成。
令 F 为显示文件时间的函数,该文件必须可按字典顺序排序 yyyy-mm-dd 等,(取决于操作系统?)
R,运行目录的递归函数:
最后
This could be done with a recursive function in Bash too.
Let F be a function that displays the time of file which must be lexicographically sortable yyyy-mm-dd, etc., (OS-dependent?)
R, the recursive function that runs through directories:
And finally