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

ls -altR . | head -n 3

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


当前回答

在使用基于查找的解决方案多年之后,我发现自己希望能够排除像.git这样的目录。

我改用了这个基于rsync的解决方案。把这个放到~/bin/findlatest中:

#!/bin/sh
# Finds most recently modified files.
rsync -rL --list-only "$@" | grep -v '^d' | sort -k3,4r | head -5

现在是findlatest。将列出最近修改的5个文件,并查找latest—exclude .git。将列出。git中不包括的5个。

这是通过利用一些很少使用的rsync功能来实现的:“如果一个单一的源参数被指定为[rsync]而没有目的地,那么文件将以类似于ls -l的输出格式列出”(rsync手册页)。

与基于rsync的备份工具结合使用时,接受rsync参数的能力非常有用。例如,我使用rsnapshot,我用rsnapshot.conf行备份一个应用程序目录:

backup  /var/atlassian/application-data/jira/current/   home    +rsync_long_args=--archive --filter="merge /opt/atlassian/jira/current/backups/rsync-excludes"

rsync- excluded列出了我不想备份的目录:

- log/
- logs/
- analytics-logs/
- tmp/
- monitor/*.rrd4j

我现在可以看到最新的文件,将备份:

findlatest /var/atlassian/application-data/jira/current/ --filter="merge /opt/atlassian/jira/current/backups/rsync-excludes"

其他回答

这给出了一个排序的列表:

find . -type f -ls 2>/dev/null | sort -M -k8,10 | head -n5

通过在sort命令中添加'-r'来颠倒顺序。如果你只想要文件名,在'| head'之前插入"awk '{print $11}' |"

查询/target_directory目录下的所有子目录下,在过去60分钟内被修改过的文件。

$ find /target_directory -type f -mmin -60

要查找最近修改的文件,按更新时间的相反顺序排序(即,最近更新的文件在前面):

$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r

你可以使用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'

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

我已经使用了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'

此外,这也适用于mawk。

这将递归地将当前目录中所有目录的修改时间更改为每个目录中的最新文件:

for dir in */; do find $dir -type f -printf '%T@ "%p"\n' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done

我一直在使用类似的东西,以及最近修改的文件的top-k列表。对于大型目录树,避免排序会快得多。如果是最近修改最多的文件:

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

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