如何递归查找和列出具有子目录和时间的目录中的最新修改文件?

fre*_*rik 390 linux filesystems recursion time

  • 操作系统:Linux

  • 文件系统类型:ext3

  • 首选解决方案:bash(script/oneliner),ruby,python

我有几个目录,其中包含几个子目录和文件.我需要列出所有这些目录,这些目录的构造方式使得每个第一级目录都列在其中最新创建/修改的文件的日期和时间旁边.

为了澄清,如果我触摸文件或将其内容修改为几个子目录级别,那么该时间戳应该显示在第一级目录名称旁边.假设我有一个像这样结构化的目录:

./alfa/beta/gamma/example.txt
Run Code Online (Sandbox Code Playgroud)

我修改了文件的内容example.txt,我需要alfa以人类可读的形式显示在第一级目录旁边的时间,而不是epoch.我试着用find,有些事xargs,sort和喜欢,但我不能解决该问题得到,当我创建/修改文件几级向下"阿尔法"的文件系统时间戳不会改变.

小智 453

试试这个:

#!/bin/bash
find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head
Run Code Online (Sandbox Code Playgroud)

与路径,它应该递归开始扫描(它支持文件名带空格)的目录执行它.

如果有很多文件,它可能需要一段时间才能返回任何内容.如果我们改用,性能可以提高xargs:

#!/bin/bash
find $1 -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head
Run Code Online (Sandbox Code Playgroud)

这有点快.

  • 您的"快速方法"也应该能够使用print0来支持文件名中的空格甚至换行.这是我使用的:`find $ 1 -type f -print0 | xargs -0 stat --format'%Y:%y%n'| sort -nr | cut -d:-f2- | 头部.这对我来说仍然很快. (128认同)
  • 你不需要运行`stat`,因为`find PATH -type f -printf"%T @%p \n"| sort -nr`完成这项工作.它的速度也快一点. (36认同)
  • 在Mac OS X上,它不是GNU的stat,因此命令失败.你必须`brew install coreutils`并使用`gstat`而不是`stat` (18认同)
  • 我们可以以某种方式将@ user37078的评论变成实际答案或编辑原始答案吗?这似乎是"正确的方式"[tm]. (4认同)
  • 在Mac OS X上,无需安装gstat或其他任何东西,你可以这样做:`find PATH -type f -exec stat -f"%m%N""{}"\; | sort -nr | head` (4认同)
  • 我正在查看的一些目录不允许我对它们进行"统计",所以我做了以下更改(对于'fast'),所以我没有看到最终输出中的错误.`find $ {1} -type f | xargs stat --format'%Y:%y%n'2>/dev/null | sort -nr | cut -d:-f2-` (3认同)

ima*_*man 182

要在N分钟前找到上次更改文件状态的所有文件:

find -cmin -N

例如:

find -cmin -5

  • 非常好,也可以使用'find -ctime -50'作为最近50天的变化. (18认同)
  • +1谢谢,非常有用.在Windows上使用GnuWin32查找. (4认同)
  • 通常我希望“find -type f”而不是“find”仅显示文件,而不是目录。 (2认同)

小智 38

GNU Find(请参阅参考资料man find)有一个-printf参数,用于显示文件EPOC mtime和相对路径名.

redhat> find . -type f -printf '%T@ %P\n' | sort -n | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)

  • 另一个评论:当有文件名包含空格时,'awk'{print $ 2}''部分似乎会引起问题.这是一个使用`sed`的解决方案,它还会打印除路径之外的时间:`find.-type f -printf'%T @%Tc%P \n'| sort -n | 尾巴| sed -r's/^.{22} //'` (8认同)
  • 谢谢!这是唯一能够在合理的时间内搜索我的非常宽的目录结构的答案.我通过`tail`传递输出,以防止在输出中打印数千行. (3认同)
  • 我认为它应该是排序-rn (3认同)
  • -printf变体比每次调用'stat'进程要快得多 - 它减少了我的备份工作的时间.谢谢你让我意识到这一点.我避免了awk/sed的事情,因为我只关心树中的最后一次更新 - 所以X = $(找/路径类型f -printf'%T%p \n'| grep -v something-I- don-tcare-about | sort -nr | head -n 1)和echo $ {X#*""}对我来说效果很好(把东西放到第一个空间) (2认同)
  • 如果文件名跨多行,则全部无效.使用`touch"lala <Enter> b"`创建这样的文件.我认为unix实用程序设计对文件名有很大的缺陷. (2认同)

sla*_*tir 34

我缩短了光环对这个单线的真棒答案

stat --printf="%y %n\n" $(ls -tr $(find * -type f))
Run Code Online (Sandbox Code Playgroud)

更新:如果文件名中有空格,则可以使用此修改

OFS="$IFS";IFS=$'\n';stat --printf="%y %n\n" $(ls -tr $(find . -type f));IFS="$OFS";
Run Code Online (Sandbox Code Playgroud)

  • 如果您有大量文件,这将不起作用.使用xargs的答案解决了这个限制. (3认同)

Dan*_*mer 17

试试这个

#!/bin/bash
stat --format %y $(ls -t $(find alfa/ -type f) | head -n 1)
Run Code Online (Sandbox Code Playgroud)

它用于find收集目录中的所有文件,ls列出按修改日期排序的head文件,用于选择第一个文件,最后stat以漂亮的格式显示时间.

此时,对于名称中包含空格或其他特殊字符的文件,这是不安全的.如果它还不能满足您的需求,请写一个表扬.

  • halo:我喜欢你的回答,它运行良好并且打印出正确的文件。然而,我没有帮助我,因为在我的情况下有太多的子级别。所以我得到 ls 的“参数列表太长”......在这种情况下 xargs 也无济于事。我会试试别的。 (2认同)

Jim*_*unt 10

此命令适用于Mac OS X:

find "$1" -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head

在Linux上,正如原始海报所要求的那样,使用stat而不是gstat.

当然,这个答案是user37078的杰出解决方案,从评论推广到完整答案.我把CharlesB的洞察力混合在gstatMac OS X 上使用.顺便说一句,我从MacPorts获得了coreutils而不是自制软件.

以下是我将其打包成一个简单~/bin/ls-recent.sh的重用命令的方法:

#!/bin/bash
# ls-recent: list files in a dir tree, most recently modified first
#
# Usage: ls-recent path [-10 | more]
# 
# Where "path" is a path to target directory, "-10" is any arg to pass
# to "head" to limit the number of entries, and "more" is a special arg
# in place of "-10" which calls the pager "more" instead of "head".
if [ "more" = "$2" ]; then
   H=more; N=''
else
   H=head; N=$2
fi

find "$1" -type f -print0 |xargs -0 gstat --format '%Y :%y %n' \
    |sort -nr |cut -d: -f2- |$H $N
Run Code Online (Sandbox Code Playgroud)

  • 对于那些不想在Mac OS X上安装任何东西的人:`find.-exec stat -f'%m%t%Sm%N'{} + | sort -n | cut -f2-` (8认同)
  • 在OS X优胜美地上;我收到错误消息:查找:ftsopen:没有这样的文件或目录 (2认同)

Wil*_*Niu 5

这篇文章中的perl和Python解决方案都帮助我在Mac OS X上解决了这个问题:https://unix.stackexchange.com/questions/9247/how-to-list-files-sorted-by-modification-date-recursively -no-stat-command-avail.

从帖子引用:

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
    }'
Run Code Online (Sandbox Code Playgroud)

蟒蛇:

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'
Run Code Online (Sandbox Code Playgroud)


anu*_*ava 5

这是一个适用于可能包含空格、换行符和全局字符的文件名的版本:

find . -type f -printf "%T@ %p\0" | sort -zk1nr
Run Code Online (Sandbox Code Playgroud)
  • find ... -printf打印文件修改时间(纪元值),后跟空格和\0终止文件名。
  • sort -zk1nr读取以 NUL 结尾的数据并按数字反向排序

由于问题是用 Linux 标记的,我假设GNU 核心实用程序可用。

您可以使用以下命令对上述内容进行管道传输:

xargs -0 printf "%s\n"
Run Code Online (Sandbox Code Playgroud)

打印修改时间和按修改时间排序的文件名(最近的在前),以换行符结尾。


Ser*_*ndt 5

忽略隐藏的文件-具有良好且快速的时间戳

很好地处理文件名中的空格-并非您应该使用它们!

$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10

2017.01.28 07h00 Sat ./recent
2017.01.21 10h49 Sat ./hgb
2017.01.16 07h44 Mon ./swx
2017.01.10 18h24 Tue ./update-stations
2017.01.09 10h38 Mon ./stations.json
Run Code Online (Sandbox Code Playgroud)

find通过以下链接可以找到更多丰富的信息。


Sew*_*iec 5

这就是我正在使用的(非常有效):

function find_last () { find "${1:-.}" -type f -printf '%TY-%Tm-%Td %TH:%TM %P\n' 2>/dev/null | sort | tail -n "${2:-10}"; }
Run Code Online (Sandbox Code Playgroud)

优点:

  • 它只产生 3 个进程

用法:

find_last [dir [number]]
Run Code Online (Sandbox Code Playgroud)

在哪里:

  • dir - 要搜索的目录 [当前目录]
  • number - 要显示的最新文件数 [10]

输出find_last /etc 4如下所示:

2019-07-09 12:12 cups/printers.conf
2019-07-09 14:20 salt/minion.d/_schedule.conf
2019-07-09 14:31 network/interfaces
2019-07-09 14:41 environment
Run Code Online (Sandbox Code Playgroud)