我想查找当前文件夹中的所有目录和子目录,不包括那些隐藏的(或属于隐藏的)。以下不起作用:
find . -type d -name "[!.]*"
Run Code Online (Sandbox Code Playgroud)
因为我认为它只会避免空的隐藏文件夹。这样的东西是匹配的
./.cache/totem
Run Code Online (Sandbox Code Playgroud)
我假设您将以点开头的目录分类为“隐藏”。为避免进入此类目录,您应该使用-prune
.
find . -mindepth 1 -type d \( -name '.*' -prune -o -print \)
Run Code Online (Sandbox Code Playgroud)
这从当前目录开始(我们可以在*
此处指定,但前提是您的通配符未设置为包含点文件/目录 - 例如bash
's dotglob
)。然后它只匹配目录,而不考虑.
自身。括号中的部分find
表示,如果名称匹配,.*
则将对其进行修剪,以便不再考虑它及其后代;否则打印其名称。
如果您没有(非 POSIX)-mindepth
选项,则可以使用此替代方法。可以说这比我建议的原始解决方案更好,但我将两者都留在答案中
find . -type d \( -name '.?*' -prune -o -print \)
Run Code Online (Sandbox Code Playgroud)
zsh
:print -rC1 -- **/*(N/)
Run Code Online (Sandbox Code Playgroud)
(zsh globs 默认跳过隐藏文件)。
或者对这些目录做任何事情:
for dir (**/*(N/)) anything with $dir
Run Code Online (Sandbox Code Playgroud)
或者,如果一次anything
可以处理多个文件,使用 GNUxargs
或兼容:
xargs -r0a <(print -rNC1 -- **/*(N/)) anything with
Run Code Online (Sandbox Code Playgroud)
LC_ALL=C find . -name '.?*' -prune -o -type d -print
Run Code Online (Sandbox Code Playgroud)
LC_ALL=C
是必需的,否则它将无法跳过名称包含在用户语言环境中不构成有效字符的字节序列的隐藏目录。又见谓词的顺序如何确保我们避免应用-type d
(这可能需要额外的昂贵的lstat()
系统调用)上的名字开始与这些文件.
。
那个也输出.
(当前工作目录),如果你不想要它,请在! -name .
之前添加一个-type
或将其更改为:
LC_ALL=C find . ! -name . \( -name '.*' -prune -o -type d -print \)
Run Code Online (Sandbox Code Playgroud)
对文件做任何事情,替换-print
为-exec anything with {} ';'
或者-exec anything with {} +
如果anything
可以一次处理多个文件。