如何在通配符嵌入的“查找”搜索中排除/忽略隐藏的文件和目录?


119

从开始(请注意“某些文本” 之前和之后通配符

find . -type f -name '*some text*'

如何排除/忽略所有隐藏的文件和目录?

我已经搜寻Google太久了,碰到了一些修剪和!(惊叹号)的参数,但没有接头(和吝啬),例如这只是工作

管道 |grep将是一个选择,我还欢迎这样的例子; 但主要是我感兴趣的是一个简短的一行(或一对夫妇单独单行的,说明实现相同的命令行目标的不同方式),只是使用find

ps:在linux中查找文件并排除特定目录似乎密切相关,但a)尚不被接受,b)是相关的,但有所不同,但是c)可能会提供启发并帮助查明混乱!

编辑

find . \( ! -regex '.*/\..*' \) -type f -name "whatever",有效。正则表达式查找“​​任何东西,然后是斜杠,然后是点,然后是任何东西”(即所有隐藏的文件和文件夹,包括其子文件夹)和“!” 否定正则表达式。


对于您在编辑中提出的问题没有帮助,但请在此处查看我的问题及其答案:unix.stackexchange.com/q/69164/15760以及答案中的链接。

Answers:


134

这将打印出属于目录的所有文件,并跳过隐藏的文件和目录:

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

请注意最后一个,最后需要它-print!另外,不确定-name '\.*' would be more efficient instead of -path`(因为该路径正在搜索子路径,但这些路径将被删除)
artfulrobot 2014年

.在这种情况下,它的特殊含义是什么?
弗罗斯特斯2015年

@frostschutz后的点find表示当前目录:find将查看当前目录下的所有文件和目录。之后的参数path是一个正则表达式,其中的点通常表示“任何字符”,以使其表示文字点,我们必须使用反斜杠对其进行转义。经过争论之后-name 是不是一个正则表达式,但它扩展通配符像?*像一个外壳程序。
Flimm

2
@frostschutz实际上,想起来,我可能.有特殊含义是错误的。
Flimm

1
@Flimm是的,无需逃脱.。据我所知,只有这些需要进行转义:*?,和[]
thdoan '17

10

这是排除点文件的几种方法之一,这些点文件也可以在BSD,Mac和Linux上正常工作:

find "$PWD" -name ".*" -prune -o -print
  • $PWD 打印当前目录的完整路径,这样路径就不会以 ./
  • -name ".*" -prune 匹配以点开头但不降序的所有文件或目录
  • -o -print表示如果前一个表达式不匹配则打印文件名。默认情况下,使用-print-print0导致所有其他表达式不打印。

请解释/详细说明“令人震惊的复杂”;已经给出的答案和您的答案似乎提供了相反的证据……?
关于natty的坚果,2016年

2
“令人震惊的复杂”可能太过分了。我改写了答案,直达重点。我认为我发布的答案很难理解,而且如果不仔细阅读手册页就很难看到。如果使用GNU find,那么还有更多可能的解决方案。
埃德曼

-o ... -print是有帮助的。对于我来说,现在有了find ... '!' -name . -name '.*' -prune -o ... -print,它比包含$ PWD更方便。
罗杰·佩特

4
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)

排除所有隐藏目录和$ DIR下的隐藏文件


这是完美的答案。它递归查找所有文件,但不包括目录和隐藏文件的行项目。谢谢!
KyleFarris 2015年

2

我最初发布的答案是对上述原始问题的“编辑”:

find . \( ! -regex '.*/\..*' \) -type f -name "whatever",有效。正则表达式查找“​​任何东西,然后是斜杠,然后是点,然后是任何东西”(即所有隐藏的文件和文件夹,包括其子文件夹)和“!” 否定正则表达式。


类似,但仅适用于当前文件夹:find . \( ! -regex './\..*' \) -type f -maxdepth 1 -print
phyatt

2

您不必为此使用find。只需在shell中自行使用globstar,例如:

echo **/*foo*

要么:

ls **/*foo*

其中,**/递归表示任何文件夹以及名称*foo*中包含的任何文件foo

默认情况下,using ls将打印文件名,但不包括隐藏文件和目录。

如果您没有启用通配符,请通过进行shopt -s globstar

注意:一个新的globbing选项可在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

5
您不需要ls那!echo **/*foo*
凯文·考克斯

@kenorb(和@ kevin-cox)。你能说得更详细些吗?为什么globstar(= *)在这里工作以及如何工作?斜杠是做什么的?
关于natty的坚果,

@nuttyaboutnatty /表示文件夹,它将目录与文件名分开。*基本上代表了一切。
kenorb

@kenorb是的,但是:一线对原始问题有何帮助?
关于natty的胡言乱语

1
@nuttyaboutnatty阐明并添加了示例。通过查找忽略隐藏文件的文件,它会有所帮助。
kenorb

1

@Flimm的答案很好,特别是因为它可以防止find下降到隐藏目录中。我更喜欢这种简化:

通常排除所有隐藏的路径(常规文件,目录等):

find <start-point> -path '*/.*' -prune -o <expression> -print

例如,使用您的工作目录作为起点和-name '*some text*'表达式:

find . -path '*/.*' -prune -o -name '*some text*' -print

与@Flimm的答案相反,简单的情况是没有隐藏的文件或目录。该-path '*/.*'表达式对于.文件分隔符后紧跟的任何路径(常规文件,目录等)都是正确的/。因此,此行将修剪隐藏文件和目录。

在允许排除隐藏目录的同时允许隐藏文件的情况需要进一步过滤。这是您要-type d在要删除的表达式中包括的位置。

find <start-point> -type d -path '*/.*' -prune -o <expression> -print 

例如:

find . -type d -path '*/.*' -prune -o -name '*some text*' -print

在这种情况下-type d -path '*/.*'true仅适用于目录,因此仅修剪目录。


0

find具有精巧的逻辑开关,例如-and-not您可以利用它们来利用两个规则来查找匹配文件,例如:

$ touch non_hidden_file.txt .hidden_file.txt somethings/.another_hidden_file.txt                                                 

$ find . -type f -name '*hidden_file*' -and \( -not -name ".*" \)                            
./non_hidden_file.txt

如您所见,find使用两个规则 -name '*hidden_file*'-and \( -not -name ".*" \)查找与两个条件都匹配的文件名-文件名中包含hidden_file但不带前导点。请注意括号前面的斜杠-它们用于将括号定义为find参数,而不是定义子外壳(括号中的含义是没有斜杠)


0
$ pwd
/home/victoria

$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2

$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2

笔记:

  • . :当前文件夹
  • 删除-maxdepth 1以递归搜索
  • -type f:查找文件,而不是目录(d
  • -not -path '*/\.*' :不返回 .hidden_files
  • sed 's/^\.\///g'./从结果列表中删除前置的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.