问题描述
从(注意”some text”之前和之后的通配符)
find . -type f -name '*some text*'
如何排除/忽略所有隐藏的文件和目录?
我已经been googling for far too long,遇到了一些普朗和! (感叹号)参数,但没有适合(和简洁)的例子,只是工作。
管道|
grep
将是一个选项,我也欢迎这样的例子;但主要是我只使用find
对一个简短的one-liner(或几个stand-alone one-liners,说明实现相同命令行目标的不同方式)感兴趣。
ps:Find files in linux and exclude specific directories似乎密切相关,但a)尚未被接受,b)为related-but-different-and-distinct,但c)可能会提供灵感并帮助查明混淆!
编辑
find . \( ! -regex '.*/\..*' \) -type f -name "whatever"
,工作。正则表达式查找“任何东西,然后斜杠,然后一个点,然后任何东西”(即所有隐藏的文件和文件夹,包括他们的子文件夹),并且”!”否定正则表达式。
最佳解决方案
这会打印作为目录后代的所有文件,并跳过隐藏的文件和目录:
find . -not -path '*/\.*'
因此,如果您正在寻找名称中包含some text
的文件,并且您想跳过隐藏的文件和目录,请运行:
find . -not -path '*/\.*' -type f -name '*some text*'
说明:
-path
选项运行检查整个路径字符串的模式。 *
是一个通配符,/
是一个目录分隔符,\.
是一个点(它必须被转义以避免特殊含义),而*
是另一个通配符。 -not
表示不选择与此测试相匹配的文件。
我不认为find
足够聪明,可以避免在上一个命令中递归搜索隐藏目录,所以如果您需要速度,请改用-prune
,如下所示:
find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*some text*' -print
次佳解决方案
这是排除dot-files的少数方法之一,它也可以在BSD,Mac和Linux上正常工作:
find "$PWD" -name ".*" -prune -o -print
-
$PWD
打印当前目录的完整路径,以便路径不以./
开头 -
-name ".*" -prune
匹配任何以点开头然后不下降的文件或目录 -
-o -print
表示如果前面的表达式不匹配任何内容,则打印文件名。使用-print
或-print0
会导致默认情况下不打印所有其他表达式。
第三种解决方案
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)
排除$ DIR下的所有隐藏目录和隐藏文件
第四种方案
我最初作为”edit”发布的答案符合我上面的原始问题:
find . \( ! -regex '.*/\..*' \) -type f -name "whatever"
,工作。正则表达式查找“任何东西,然后斜杠,然后一个点,然后任何东西”(即所有隐藏的文件和文件夹,包括他们的子文件夹),并且”!”否定正则表达式。
第五种方案
你不必为此使用find
。只需在shell it-self中使用globstar,如:
echo **/*foo*
要么:
ls **/*foo*
**/
以递归方式表示任何文件夹,*foo*
以foo
为名称的任何文件。
默认情况下,使用ls
将打印除隐藏文件和目录之外的文件名。
如果您没有启用通配符,请通过shopt -s globstar
执行。
注意:A new globbing option在Bash 4,zsh和类似的shell中工作。
例:
$ mkdir -vp a/b/c/d
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
mkdir: created directory 'a/b/c/d'
$ touch a/b/c/d/foo a/b/c/d/bar a/b/c/d/.foo_hidden a/b/c/d/foo_not_hidden
$ echo **/*foo*
a/b/c/d/foo a/b/c/d/foo_not_hidden