为什么在传递到当前目录而不是路径时,Find会返回不同的排序结果? [英] Why does find return different, sorted results when passed the current directory versus a path?
问题描述
我正在尝试编写一个Shell命令,返回最近修改的文件。
但是,该目录包含的文件超过了ls
可以直接容纳的范围(因此使用find
,我认为这是通过管道传输到其他命令的正确解决方案)。
在这样做的过程中,我遇到了在目录中运行find .
和传递目录以查找(即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 .
和find ~/Downloads
而改变。
是怎么回事?我有一种模糊的直觉,这可能与我们正在查看inode的更改时间以及包含目录更改…有关一些东西。
提前谢谢!请注意,虽然我也对我的特定排序问题的解决方案感兴趣,但我最感兴趣的是了解为什么会出现差异。
推荐答案
xargs
的工作是拆分超出系统可容纳范围的命令行。为了说明起见,我们假设您有四个文件和一个操作系统,其中ARG_MAX
只有25个字节(尽管在现实生活中,它在现代系统上大约是MB)。然后在没有路径的情况下,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
调用的最新文件。
在装有GNUfind
(Linux等)的系统上,使用其-printf
选项格式化修改时间在文件名之前的字符串。
find . -type f -printf "%T+ %p " |
sort -rnz |
perl -n000 's/^[^ ]+ //; print; exit'
我们按修改时间排序,然后丢弃修改时间,只打印文件名。空分隔符负责处理包含换行符的文件名;此功能尤其是GNU扩展名。
如果您没有GNU实用程序,可以将find -exec stat
与类似的格式字符串一起使用;遗憾的是,stat
的这一功能也没有标准化,但应该不难找到适用于BSD、MacOS等非Linux系统的示例。
这篇关于为什么在传递到当前目录而不是路径时,Find会返回不同的排序结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!