为什么 find return 在传递当前目录和路径时会得到不同的排序结果?
Why does find return different, sorted results when passed the current directory versus a path?
我正在尝试编写 shell 命令 returning 最近修改的文件。
但是,该目录中的文件多于 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
不是同一个文件。 我如何解释为什么这些命令似乎 return 不同的结果?
作为参考,这里是目录中 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
,看来 change 时间实际上比 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
的工作是拆分超过系统可容纳的命令行。为了便于说明,我们假设您有四个文件和一个 OS,其中 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
仍将 return 是第一个 ls
调用的最新文件。
在具有 GNU find
(Linux 等)的系统上,使用其 -printf
选项格式化一个字符串,其中修改时间在文件名之前。
find . -type f -printf "%T+\t%p[=12=]" |
sort -rnz |
perl -n000 's/^[^\t]+\t//; print; exit'
我们按修改时间排序,然后丢弃修改时间,只打印文件名。空定界符负责处理其中包含换行符的文件名;此功能尤其是 GNU 扩展。
如果您没有 GNU 实用程序,您可以使用 find -exec stat
和类似的格式字符串;不幸的是,stat
的这个特性也没有标准化,但是不难找到 non-Linux 系统的例子,比如 BSD、macOS 等
我正在尝试编写 shell 命令 returning 最近修改的文件。
但是,该目录中的文件多于 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
不是同一个文件。 我如何解释为什么这些命令似乎 return 不同的结果?
作为参考,这里是目录中 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
,看来 change 时间实际上比 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
的工作是拆分超过系统可容纳的命令行。为了便于说明,我们假设您有四个文件和一个 OS,其中 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
仍将 return 是第一个 ls
调用的最新文件。
在具有 GNU find
(Linux 等)的系统上,使用其 -printf
选项格式化一个字符串,其中修改时间在文件名之前。
find . -type f -printf "%T+\t%p[=12=]" |
sort -rnz |
perl -n000 's/^[^\t]+\t//; print; exit'
我们按修改时间排序,然后丢弃修改时间,只打印文件名。空定界符负责处理其中包含换行符的文件名;此功能尤其是 GNU 扩展。
如果您没有 GNU 实用程序,您可以使用 find -exec stat
和类似的格式字符串;不幸的是,stat
的这个特性也没有标准化,但是不难找到 non-Linux 系统的例子,比如 BSD、macOS 等