目录中的文件数,其中文件名可能有新行(或任何其他奇怪的字符)

use*_*842 0 shell posix

我想知道特定目录中的项目数(文件、子目录等)。

似乎有很多关于它的问题,但大多数(如果不是全部)答案似乎都依赖于wc -l. 例如:

ls -1 | wc -l

但是,如果一个或多个文件的名称中有新行,这将给出错误的答案。这里的另一个问题是ls -1可能返回的不仅仅是文件。

一个不可移植的答案隐藏在数千个类似问题之一的评论中。有效,但不幸的是它依赖-printf于我的发行版中不可用的。

find -maxdepth 1 -type f -printf "\n" | wc -l (by Godlygeek)

是否有更便携的解决方案可以正确处理名称中包含任何字符的文件?

Ste*_*itt 6

假设您不需要位置参数,您可以设置它们并计算它们:

set -- .* *
echo $#
Run Code Online (Sandbox Code Playgroud)

这可以在函数或子shell中,以限制以下内容的影响set

countfiles() {
    set -- .* *
    echo $#
}

countfiles
Run Code Online (Sandbox Code Playgroud)

或者

(set -- .* *; echo $#)
Run Code Online (Sandbox Code Playgroud)

只有函数或子shell 的参数在这里“丢失”,主上下文中的位置参数未受影响。

您也可以指定路径:

set -- path/to/dir/.* path/to/dir/*
echo $#
Run Code Online (Sandbox Code Playgroud)

隐藏文件的确切扩展将取决于 shell 设置;POSIX shell 应该在扩展时包含....*,因此这些将被计算在内。如果您不想计算它们,请检查它们是否包含在内(查看$1$2),然后从结果中减去 2。

在某些 shell 中,可以配置点扩展,和/或其他扩展 ( .[^.]* ..?*) 可用于排除...;因此在 Bash 中,使用dotglob

shopt -s dotglob
set -- *
echo $#
Run Code Online (Sandbox Code Playgroud)