如何在具有子目录和时间的目录中递归查找并列出最新修改的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5566310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to recursively find and list the latest modified files in a directory with subdirectories and times?
提问by fredrik
Operating system: Linux
Filesystem type: ext3
Preferred solution: bash (script/oneliner), ruby, python
操作系统:Linux
文件系统类型:ext3
首选解决方案:bash(脚本/oneliner)、ruby、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 likes 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.
并且我修改了文件的内容example.txt
,我需要将时间alfa
以人类可读的形式显示在一级目录旁边,而不是纪元。我已经使用find尝试了一些东西,xargs
,sort
和喜欢,但我不能得到解决,当我创建“阿尔法”的文件系统时间戳不会更改/修改文件几级下降的问题。
回答by Daniel B?hmer
Try this
尝试这个
#!/bin/bash
stat --format %y $(ls -t $(find alfa/ -type f) | head -n 1)
It uses find
to gather all files from the directory, ls
to list them sorted by modification date, head
for selecting the 1st file and finally stat
to show the time in a nice format.
它用于find
从目录中收集所有文件,ls
按修改日期排序列出它们,head
用于选择第一个文件,最后stat
以漂亮的格式显示时间。
At this time it is not safe for files with whitespace or other special chars in their names. Write a commend if it doesn't meet your needs yet.
目前,名称中带有空格或其他特殊字符的文件是不安全的。如果它还不能满足您的需求,请写一个推荐。
回答by graugans
You may give the printf command of find a try
您可以尝试使用 printf 命令查找
%Ak File's last access time in the format specified by k, which is either
@' or a directive for the C
strftime' function. The possible values for k are listed below; some of them might not be available on all systems, due to differences in `strftime' between systems.
%Ak 文件的最后访问时间,采用 k 指定的格式,它是
@' or a directive for the C
strftime' 函数。下面列出了 k 的可能值;由于系统之间`strftime'的差异,其中一些可能并非在所有系统上都可用。
回答by Heppo
Try this one:
试试这个:
#!/bin/bash
find -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head
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:
如果有很多文件,它可能需要一段时间才能返回任何内容。如果我们xargs
改为使用,可以提高性能:
#!/bin/bash
find -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head
which is a bit faster.
这有点快。
回答by slashdottir
I shortened halo's awesome answer to this one-liner
我缩短了光环对这个单线的精彩回答
stat --printf="%y %n\n" $(ls -tr $(find * -type f))
Updated: If there are spaces in filenames, you can use this modification
更新:如果文件名中有空格,您可以使用此修改
OFS="$IFS";IFS=$'\n';stat --printf="%y %n\n" $(ls -tr $(find . -type f));IFS="$OFS";
回答by William Niu
Both the perl and Python solutions in this post helped me solve this problem on Mac OS X: https://unix.stackexchange.com/questions/9247/how-to-list-files-sorted-by-modification-date-recursively-no-stat-command-avail.
这篇文章中的 perl 和 Python 解决方案都帮助我在 Mac OS X 上解决了这个问题:https: //unix.stackexchange.com/questions/9247/how-to-list-files-sorted-by-modification-date-recursively -no-stat-command-avail。
Quoting from the post:
引用帖子:
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:
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'
回答by Izkata
For plain ls
output, use this. There is no argument list, so it can't get too long:
对于普通ls
输出,请使用它。没有参数列表,所以它不能太长:
find . | while read FILE;do ls -d -l "$FILE";done
And niceified with cut
for just the dates, times, and name:
并仅对cut
日期、时间和名称进行优化:
find . | while read FILE;do ls -d -l "$FILE";done | cut --complement -d ' ' -f 1-5
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:
编辑:刚刚注意到当前的最佳答案按修改日期排序。对于这里的第二个示例,这也很容易,因为修改日期在每一行的第一个 - 在最后进行排序:
find . | while read FILE;do ls -d -l "$FILE";done | cut --complement -d ' ' -f 1-5 | sort
回答by Nahuel Fouilleul
This could be done with a reccursive function in bash too
这也可以通过 bash 中的递归函数来完成
Let F a function that displays the time of file which must be lexicographically sortable yyyy-mm-dd etc., (os-dependent?)
让 F 显示文件时间的函数,该文件必须按字典顺序排序 yyyy-mm-dd 等,(依赖于操作系统?)
F(){ stat --format %y "";} # Linux
F(){ ls -E ""|awk '{print" "}';} # SunOS: maybe this could be done easier
R the recursive function that run through directories
R 遍历目录的递归函数
R(){ local f;for f in ""/*;do [ -d "$f" ]&&R $f||F "$f";done;}
And finally
最后
for f in *;do [ -d "$f" ]&&echo `R "$f"|sort|tail -1`" $f";done
回答by Sean
I'm showing this for latest access time, you can easily modify this to do latest mod time.
我显示的是最新访问时间,您可以轻松修改它以执行最新的修改时间。
There is two ways to do this:
有两种方法可以做到这一点:
1)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)
1)如果您想避免全局排序,如果您有数千万个文件,这可能会很昂贵,那么您可以这样做:(将自己定位在您希望开始搜索的目录的根目录中)
linux> touch -d @0 /tmp/a;
linux> find . -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 ; -print
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".
上面的方法打印访问时间逐渐更新的文件名,它打印的最后一个文件是访问时间最新的文件。您显然可以使用“tail -1”获得最新的访问时间。
2)You can have find recursively print the name,access time of all files in your subdirectory and then sort based on access time and the tail the biggest entry:
2)您可以递归打印子目录中所有文件的名称,访问时间,然后根据访问时间和尾部最大条目进行排序:
linux> \find . -type f -exec stat --printf="%X %n\n" {} \; | \sort -n | tail -1
And there you have it...
你有它...
回答by user2570243
GNU Find (see man find
) has a -printf
parameter for displying the files EPOC mtime and relative path name.
GNU Find(请参阅参考资料man find
)有一个-printf
用于显示文件 EPOC mtime 和相对路径名的参数。
redhat> find . -type f -printf '%T@ %P\n' | sort -n | awk '{print }'
回答by iman
To find all files that file status was last changed Nminutes ago:
要查找N分钟前上次更改文件状态的所有文件:
find -cmin -N
find -cmin -N
for example:
例如:
find -cmin -5
find -cmin -5