操作系统:Linux 文件系统类型:ext3 首选解决方案:Bash(脚本/一行程序)、Ruby或Python

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

为了说明这一点,如果我接触一个文件或修改它的内容向下几级子目录,该时间戳应该显示在第一级目录名旁边。假设我有一个这样的目录:

./alfa/beta/gamma/example.txt

我修改了文件example.txt的内容,我需要在第一级目录alfa旁边以人类可读的形式显示时间,而不是epoch。我已经尝试了一些使用find, xargs, sort和类似的东西,但我不能绕过“alfa”的文件系统时间戳不改变的问题,当我创建/修改文件的几个级别。


当前回答

试试这个:

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

在执行它时,使用它应该开始递归扫描的目录的路径(它支持带空格的文件名)。

如果有很多文件,它可能需要一段时间才能返回任何东西。如果我们使用xargs来代替,性能可以得到改善:

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

这样会快一点。

其他回答

这实际上应该做OP指定的事情:

Bash中的一行代码:

$ for first_level in `find . -maxdepth 1 -type d`; do find $first_level -printf "%TY-%Tm-%Td %TH:%TM:%TS $first_level\n" | sort -n | tail -n1 ; done

给出如下输出:

2020-09-12 10:50:43.9881728000 .
2020-08-23 14:47:55.3828912000 ./.cache
2018-10-18 10:48:57.5483235000 ./.config
2019-09-20 16:46:38.0803415000 ./.emacs.d
2020-08-23 14:48:19.6171696000 ./.local
2020-08-23 14:24:17.9773605000 ./.nano

中所请求的,即使是在子文件夹中,也会列出这些文件夹中最新文件的人类可读时间戳的每个一级目录

“我需要列出所有这些被构建的目录 使每个一级目录都列在日期旁边的一种方法 以及其中最新创建/修改文件的时间。”

查询N分钟前文件状态被修改的所有文件。

find -cmin -N

例如:

find -cmin -5

使用-ctime代替-cmin:

find -ctime -3

在FreeBSD和MacOS上:您还可以使用-ctime n[smhdw]表示秒、分钟、小时、天和周。如果没有提供单位,Days是默认值。

例子:

# FreeBSD and MacOS only:
find . -ctime -30s
find . -ctime -15
find . -ctime -52w

对于简单的ls输出,使用这个。没有参数列表,所以它不能太长:

find . | while read FILE;do ls -d -l "$FILE";done

并以切割的方式将日期,时间和姓名进行了美化:

find . | while read FILE;do ls -d -l "$FILE";done | cut --complement -d ' ' -f 1-5

编辑:请注意,当前顶部的答案按修改日期排序。这里的第二个例子也很简单,因为修改日期在每行的第一个-在末尾添加一个排序:

find . | while read FILE;do ls -d -l "$FILE";done | cut --complement -d ' ' -f 1-5 | sort

@anubhava的回答很好,但不幸的是,它不能在BSD工具上工作——也就是说,它不能与macOS上默认安装的find一起工作,因为BSD find没有-printf操作符。

所以这里有一个变体,适用于macOS + BSD(在我的Catalina Mac上测试),它结合了BSD find与xargs和stat:

$ find . -type f -print0 \
      | xargs -0 -n1 -I{} stat -f '%Fm %N' "{}" \
      | sort -rn 

当我在这里时,这里是我喜欢使用的BSD命令序列,它将时间戳设置为ISO-8601格式

$ find . -type f -print0 \
    | xargs -0 -n1 -I{} \
       stat  -f '%Sm %N' -t '%Y-%m-%d %H:%M:%S' "{}" \
    | sort -rn

(注意,与@anubhava的答案不同,我的答案将文件名从find传递给xargs作为单个参数,而不是以\0终止的列表,这将改变在最后输出的内容)

下面是GNU版本(即@anubhava的答案,但是iso-8601格式):

$ gfind . -type f -printf "%T+ %p\0" | sort -zk1nr

相关问:查找缺少选项-printf,现在怎么办?

快速Bash功能:

# findLatestModifiedFiles(directory, [max=10, [format="%Td %Tb %TY, %TT"]])
function findLatestModifiedFiles() {
    local d="${1:-.}"
    local m="${2:-10}"
    local f="${3:-%Td %Tb %TY, %TT}"

    find "$d" -type f -printf "%T@ :$f %p\n" | sort -nr | cut -d: -f2- | head -n"$m"
}

在目录中查找最新修改的文件:

findLatestModifiedFiles "/home/jason/" 1

您还可以指定自己的日期/时间格式作为第三个参数。