通常当我想显示目录中第一个文件的名称时,我会输入:
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
,,stdbuf
和awk
:
ARG_MAX
请注意,如果文件过多(参数列表过长,超过字节数) ,则可能会触发此操作ARG_MAX
。在这种情况下,请使用方法 1。
- 任何 shell 内置函数(例如
printf
)echo
都可以打印文件名 - shell 通配符,
*
进行扩展(排序顺序应该与ls
给定的locale
相同LC_COLLATE
) stdbuf -o0
(stdbuf
GNU 附带coreutils
)使 STDOUT 流printf
无echo
缓冲- 将/
|
的 STDOUT 通过管道 ( ) 传送到并打印第一条记录printf
echo
awk
exit
- 退出后
awk
,stdbuf
(printf
)将收到SIGPIPE
,并将被终止 - 我将使用
printf
来获取由 ASCII NUL ( ) 分隔的文件名\0
,并将其用作\0
记录分隔符,awk
以解决与文件名有关的任何边缘情况
把它们放在一起:
stdbuf -o0 printf '%s\0' * | awk 'BEGIN{RS="\0"} {print; exit}'