shell - 为什么 find 在传递当前目录与路径时返回不同的排序结果?
问题描述
我正在尝试编写一个返回最近修改的文件的 shell 命令。但是,该目录包含的文件比ls
直接容纳的文件多(因此使用find
,我理解这是管道到其他命令的正确解决方案)。
这样做时,我遇到了find .
在目录中运行和将目录传递给 find ( ie find $folder
) 之间令人困惑的区别。
这是一个例子:
➜ echo $SHELL
/usr/local/bin/zsh
➜ pwd
/Users/aresnick/Downloads
➜ find . -type f -maxdepth 1 -print0 | xargs -0 ls -t | head -1
./DID_Codebook_2020.pdf
➜ find $(pwd) -type f -maxdepth 1 -print0 | xargs -0 ls -t | head -1
/Users/aresnick/Downloads/Profiles17_MA.pdf
➜ find /Users/aresnick/Downloads -type f -maxdepth 1 -print0 | xargs -0 ls -t | head -1
/Users/aresnick/Downloads/Profiles17_MA.pdf
请注意,DID_Codebook_2020.pdf
该文件与Profiles17_MA.pdf
. 我如何解释为什么这些命令似乎返回不同的结果?
作为参考,这里是ls -halt | head -5
目录中的输出(包括这里混淆的两个最新文件)。
➜ ls -halt | head -5
total 51229416
drwxr-xr-x+ 92 aresnick staff 2.9K Oct 12 10:34 ..
drwx------@ 4033 aresnick staff 126K Oct 12 10:02 .
-rw-r--r--@ 1 aresnick staff 1.7M Oct 12 10:02 DID_Codebook_2020.pdf
-rw-r--r--@ 1 aresnick staff 470K Oct 12 10:00 Profiles17_MA.pdf
通过 更仔细地观察stat
,似乎更改时间实际上是更新的Profiles17_MA.pdf
:
➜ stat -f "ACCESS-%Sa CHANGE-%Sc %SN" {DID_Codebook_2020.pdf,Profiles17_MA.pdf}
ACCESS-Oct 12 10:02:14 2020 CHANGE-Oct 12 10:02:08 2020 DID_Codebook_2020.pdf
ACCESS-Oct 12 10:02:14 2020 CHANGE-Oct 12 10:02:10 2020 Profiles17_MA.pdf
但是,我不明白这如何解释为什么排序顺序会随着find .
vs.改变find ~/Downloads
。
是什么赋予了? 我有一种模糊的直觉,这可能与我们正在查看 inode 的更改时间这一事实有关,以及与包括目录更改有关的某些东西……某些东西。
提前致谢!请注意,虽然我也对特定排序问题的解决方案感兴趣,但我最感兴趣的是了解为什么会出现差异。
解决方案
的工作xargs
是拆分超过系统可以容纳的命令行。让我们假设您有四个文件和一个ARG_MAX
只有 25 个字节的操作系统(尽管在现实生活中它在现代系统上大约为兆字节)。然后没有路径,xargs
运行
ls -t ./a ./b ./c ./d
但是对于完整路径,必须将命令行拆分为两个调用,以免超过命令行长度的限制:
ls -t /path/to/a /path/to/b
ls -t /path/to/c /path/to/d
当然,如果d
是您的最新文件,head
则仍然会从第一次ls
调用中返回最新文件。
在具有 GNU find
(Linux 等)的系统上,使用它的-printf
选项来格式化一个字符串,其中修改时间在文件名之前。
find . -type f -printf "%T+\t%p\0" |
sort -rnz |
perl -n000 's/^[^\t]+\t//; print; exit'
我们按修改时间排序,然后丢弃修改时间,只打印文件名。空分隔符负责处理带有换行符的文件名;这个特性尤其是一个 GNU 扩展。
如果您没有 GNU 实用程序,您可以使用find -exec stat
类似的格式字符串;不幸的是,这个特性stat
也不是标准化的,但是应该不难找到非 Linux 系统的例子,比如 BSD、macOS 等。
推荐阅读
- python - 获取第二个和第三个斜杠之间的值
- rest - 对 Azure 服务总线队列的 REST 调用
- python - 如何根据用户输入循环回到先前的意图?
- java - SQLite DELETE 查询不会从数据库中删除
- mysql - 在 SQL 中使用聚合值和非聚合值
- teradata - 将价值保留到 teradata 中的某个日期
- c# - 重定向到不同的 URL 并在 ASP.net 的地址栏中显示另一个 URL(此 URL 中的页面不存在)
- sql - 如何在 Rails 类模型范围内编写格式为 'SELECT ... FROM ... WHERE ... IN ( SELECT ... )' 的 SQL?
- java - 分配两个彼此相等的数组问题
- reactjs - 目标容器不是反应中的 DOM 元素