如何排除 .和..使用 ls 或 find?

如何排除 .和..使用 ls 或 find?

我的 home 第一层有 35 个文件和目录(没有进入子目录)。但结果是“伪造的”并报告 36,因为它们包含.特殊目录。如何排除“.”?

我已经尝试过开关-not -path,但不起作用。

find . -not -path '*/\.*' -not -path /\. -maxdepth 1|wc -l
36
find $HOME -not -path '*/\.*'  -maxdepth 1|wc -l
36

答案1

使用-mindepth

find . -mindepth 1 -maxdepth 1    |wc -l

答案2

find包括它启动的目录;从输出中排除那些,不加修饰,以获得您想要的结果:

find . -maxdepth 1 ! -path . | wc -l
find "$HOME" -maxdepth 1 ! -path "$HOME" | wc -l

(只要$HOME不包含任何会被解释为模式字符的字符,IE *, ?, [])。您还可以仅匹配名称.,将其附加(如有必要)到您感兴趣的路径:

find . -maxdepth 1 ! -name . | wc -l
find "$HOME"/. -maxdepth 1 ! -name . | wc -l

要准确计算 找到的文件数find,您应该计算文件名以外的其他内容(可以包括换行符),例如如果你find支持-printf

find . -maxdepth 1 ! -name . -printf 1 | wc -c

或者,对于 POSIX find,使用以下//技巧:

find .//. -maxdepth 1 ! -name . | grep -c //

..不是 的问题find,它不包含它,除非您显式添加它(find .....)。

ls默认情况下不会.显示..;如果您想查看隐藏文件,但不想查看...,请使用该-A选项而不是-a。使用 GNU ls,您可以要求它引用特殊字符,这将允许您准确地计算文件数量:

ls -q1A . | wc -l

答案3

仅使用! -path ..find执行测试的路径名相对于您使用的搜索路径,并且该目录将在您的示例命令中.显示。如果您使用任何其他搜索路径,您将在测试中使用它以避免列出它(例如)。.findfind "$HOME" ! -path "$HOME"

还要注意,通过使用wc -l,您实际上并不是在计算文件数,而是计算 产生的行数find,如果任何名称包含换行符,则行数可能会多于文件数。

使用 POSIX find,您可以使用

find . ! -path . -prune -exec echo x \; | wc -l 

计算当前目录中的名称数量。在这里,-prune将停止find输入任何子目录,并为每个找到的名称在一行上-exec echo x \;输出一个字符。x然后这些行将被计数wc -l

至于不显示...带有ls,则使用ls -A代替ls -a


另一种计算单个目录中的名称的方法(允许所有可能的文件名)是

shopt -s dotglob nullglob
set -- *
echo "$#"

... 在bash, 或

set -- *(DN)
echo $#

... zsh(其中(DN)修改 的行为,*以便它也匹配隐藏名称,并且如果没有匹配项,则完全删除该模式,非常类似于在 中启用dotglobnullglobshell 选项的效果bash)。

这两段代码都将位置参数设置为当前目录中的名称列表,包括隐藏名称。完成此操作后,可在特殊变量 中找到设置的位置参数的数量$#

通配模式*既不匹配.也不匹配..。即使被要求匹配隐藏的名字也不行。

yashshell 中,设置dot-globshell 选项set -o dot-glob使*匹配隐藏名称,包括和,.因此如果您使用此 shell,..您可能需要从 的值中扣除 2 。$#

答案4

最简单。作品。也许不是在文件名中嵌入换行符,但由于这是如此可怕的标准,我会说重命名这些文件。

ls -d * | wc -l

相关内容