以最佳方式获取目录中第一个文件的名称

以最佳方式获取目录中第一个文件的名称

通常当我想显示目录中第一个文件的名称时,我会输入:

ls raw/all | head -n 1

但是当目录中有很多文件时,需要很长时间


例如,对于接近 900 k 文件的目录,我们有以下测量结果:

time ls raw/all | head -n 1 

real    0m17.250s | 0m10.328s | 0m6.334s
user    0m3.224s  | 0m3.884s  | 0m3.192s
sys     0m0.544s  | 0m0.664s  | 0m0.572s

while 循环遍历所有文件需要:

time ls raw/all | wc -l

real    0m6.455s | 0m5.869s  | 0m5.228s
user    0m3.612s | 0m3.468s  | 0m4.072s
sys     0m0.460s | 0m0.784s  | 0m0.624s

如何打印第一个文件的名称高效的方式?

答案1

这很棘手。有两种方法:


方法 1 find;:

find . -mindepth 1 -print -quit

find并立即-print执行 s 找到的第一个文件-quit-mindepth 1将阻止匹配.当前目录的硬链接。

如果您只对常规文件感兴趣,请添加-type f

find . -type f  -print -quit

-mindepth 1可以被删除,因为.目录不匹配。


方法 2;sh,,stdbufawk

ARG_MAX请注意,如果文件过多(参数列表过长,超过字节数) ,则可能会触发此操作ARG_MAX。在这种情况下,请使用方法 1。

  • 任何 shell 内置函数(例如printfecho都可以打印文件名
  • shell 通配符,*进行扩展(排序顺序应该与ls给定的locale相同LC_COLLATE
  • stdbuf -o0stdbufGNU 附带coreutils)使 STDOUT 流printfecho缓冲
  • 将/|的 STDOUT 通过管道 ( ) 传送到并打印第一条记录printfechoawkexit
  • 退出后awkstdbufprintf)将收到SIGPIPE,并将被终止
  • 我将使用printf来获取由 ASCII NUL ( ) 分隔的文件名\0,并将其用作\0记录分隔符,awk以解决与文件名有关的任何边缘情况

把它们放在一起:

stdbuf -o0 printf '%s\0' * | awk 'BEGIN{RS="\0"} {print;  exit}'

相关内容