如何按日期对Find语句的结果进行排序?

如何按日期对Find语句的结果进行排序?

尝试查找名称中包含特定字符串的文件,但不知道如何对输出进行排序,在某种程度上,我只能获取文件名。

我试过了

OLDDATA=`find . -regex ".*/[0-9.]+" | ls -t`

但 ls -t 不适用于查找结果,而是适用于整个目录

编辑:此语句的结果应按修改日目录排序。此正则表达式假设匹配名称中仅包含数字和点的目录。

答案1

仅获取文件名...按修改日期排序

find+sort+cut方法:

find . -regex ".*/[0-9.]+" -printf "%T@ %f\n" | sort | cut -d' ' -f2

  • %T@- 文件的最后修改时间,在@哪里因为Jan. 1, 1970, 00:00 GMT,有小数部分

  • %f- 删除所有前导目录的文件名(仅最后一个元素)


要按降序排序:

find . -regex ".*/[0-9.]+" -printf "%T@ %f\n" | sort -k1,1r | cut -d' ' -f2

答案2

您的方法可以适应简单的情况。你面临的主要问题是你正在通过输入ls,但ls不接受任何输入。ls接受命令行参数。所以你需要传递findas的输出论点ls,使用命令替换。另外,如果目录匹配,则传递-dto 来ls列出目录本身而不是其内容。

OLDDATA=$(ls -td $(find . -regex ".*/[0-9.]+"))

仅在简单情况下,因为有两个限制:

  1. 这依赖于一个不带引号的命令替换(之后的使用也是如此$OLDDATA)。因此,它假设文件名不包含任何特殊字符(空格或通配符\[*?)。
  2. 某些版本ls可能会损坏在当前区域设置中不可打印的字符。
  3. 如果文件名的总长度太长,您将收到错误消息。 (请注意,find … -execxargs在这里无法提供帮助,因为ls必须运行一次才能使文件名的顺序正确。他们所能做的就是隐藏错误并生成未正确排序的输出 - 并在这种情况下破坏更多字符的xargs。)

执行此操作的一种强大而简单的方法是使用桀骜。它能够对通配符匹配进行排序,这要归功于全局限定符

setopt extended_glob
OLDDATA=(**/[0-9.]##(om))
  • 由于这不会调用任何其他程序,因此除了可用内存之外没有长度限制,并且在任何时候都不存在文件名损坏的风险。
  • 结果是列表字符串(每个字符串都是一个文件名),而不是一个字符串,因此它进入一个数组变量。
  • **/递归遍历子目录,避免使用find.
  • ##在 zsh 扩展 glob 语法中表示“前面的一个或多个”,它类似于+(扩展)正则表达式语法。
  • (om)是一个 glob 限定符,用于按修改时间对文件进行排序,例如ls -t.

众所周知,没有简单的方法可以使用 POSIX 工具甚至 GNU 工具和 ksh 来稳健地完成此操作。

相关内容