尝试查找名称中包含特定字符串的文件,但不知道如何对输出进行排序,在某种程度上,我只能获取文件名。
我试过了
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
接受命令行参数。所以你需要传递find
as的输出论点到ls
,使用命令替换。另外,如果目录匹配,则传递-d
to 来ls
列出目录本身而不是其内容。
OLDDATA=$(ls -td $(find . -regex ".*/[0-9.]+"))
仅在简单情况下,因为有两个限制:
- 这依赖于一个不带引号的命令替换(之后的使用也是如此
$OLDDATA
)。因此,它假设文件名不包含任何特殊字符(空格或通配符\[*?
)。 - 某些版本
ls
可能会损坏在当前区域设置中不可打印的字符。 - 如果文件名的总长度太长,您将收到错误消息。 (请注意,
find … -exec
和xargs
在这里无法提供帮助,因为ls
必须运行一次才能使文件名的顺序正确。他们所能做的就是隐藏错误并生成未正确排序的输出 - 并在这种情况下破坏更多字符的xargs
。)
执行此操作的一种强大而简单的方法是使用桀骜。它能够对通配符匹配进行排序,这要归功于全局限定符。
setopt extended_glob
OLDDATA=(**/[0-9.]##(om))
- 由于这不会调用任何其他程序,因此除了可用内存之外没有长度限制,并且在任何时候都不存在文件名损坏的风险。
- 结果是列表字符串(每个字符串都是一个文件名),而不是一个字符串,因此它进入一个数组变量。
**/
递归遍历子目录,避免使用find
.##
在 zsh 扩展 glob 语法中表示“前面的一个或多个”,它类似于+
(扩展)正则表达式语法。(om)
是一个 glob 限定符,用于按修改时间对文件进行排序,例如ls -t
.
众所周知,没有简单的方法可以使用 POSIX 工具甚至 GNU 工具和 ksh 来稳健地完成此操作。