如何根据通配符匹配以递归方式查找当前文件夹和子文件夹中的所有文件?

How can I recursively find all files in current and subfolders based on wildcard matching?

提问人:john 提问时间:5/6/2011 最后编辑:hydejohn 更新时间:9/9/2023 访问量:4328784

问:

如何根据通配符匹配以递归方式查找当前文件夹和子文件夹中的所有文件?

Linux 外壳

评论


答:

4158赞 tux21b 5/6/2011 #1

使用 find

find . -name "foo*"

find需要一个起点,所以 (dot) 指向当前目录。.

评论

34赞 IslandCow 11/16/2013
我知道这被标记为 linux,但值得一提的是:该路径对于其他非 linux 的 *nix 变体是必需的。在 linux 上,如果要使用 dot,则路径是可选的。
6赞 schumacher574 4/3/2014
@Seatter“foo*”告诉查找查找所有以“foo”开头的文件。这只是他的榜样。您可以使用“gpio*”查找名称以 gpio 开头的所有文件,或者只使用“gpio1”查找所有名为 gpio1 的文件。
57赞 grinch 5/19/2014
请注意,“foo*”用引号括起来,因此 shell 在传递它以查找之前不会展开它。如果你只是这样做了,它将被扩展,然后传递到查找。find . foo*foo*
79赞 WesternGun 10/21/2016
值得强调的是,这对于递归搜索是非常必要的。" "
32赞 Jobbo 8/15/2017
也很有用:如果您不想收到有关您无权访问的目录(或其他错误)的通知,您可以这样做find . -name "foo*" 2>/dev/null
216赞 IslandCow 5/6/2011 #2

find将查找与模式匹配的所有文件:

find . -name "*foo"

但是,如果您想要一张图片:

tree -P "*foo"

评论

24赞 DeBraid 2/21/2015
brew install tree对于未安装的 Mac OSX 用户apt-get
1赞 john-salib 2/9/2017
在macOS Sierra上测试,只需添加'--print'->'find即可。名称 “*foo” --print ' .superuser.com/questions/177289/searching-mac-through-terminal
3赞 Santosh Kumar Arjunan 3/12/2019
sudo yum install tree -y for CentOS
313赞 Paul Whipp 8/15/2012 #3

管道查找进入 grep 通常更方便;它为您提供了用于任意通配符匹配的正则表达式的全部功能。

例如,要查找文件名中不区分大小写的字符串“foo”的所有文件:

find . -print | grep -i foo

评论

109赞 iobender 8/5/2015
find还具有用于不区分大小写的通配符、正则表达式和不区分大小写的正则表达式匹配的 、 和 标志,因此不需要管道化。-iname-regex-iregexgrep
9赞 Elijah Lynn 2/9/2017
我不认为这是不必要的,而是更方便。
3赞 door_number_three 4/6/2017
但是,通过管道连接到 grep -v 可以允许您使用简单的字符串或正则表达式来删除不需要的条目。
7赞 Mr. Llama 7/6/2018
@iobender - 可悲的是,我可以从经验中告诉您,并非所有系统都带有支持这些选项的命令。有时成为唯一的选择。findgrep
1赞 alfalfasprout 7/23/2022
这里一个重要的警告是,如果你在包含大量文件的目录上使用find(例如; ''),那么这可能会很慢。
60赞 kenorb 1/14/2017 #4

如果 shell 支持新的通配选项(可通过以下方式启用):),则可以使用:shopt -s globstar

echo **/*foo*

以递归方式查找任何文件或文件夹。Bash 4、zsh 和类似的 shell 都支持这一点。


就我个人而言,我已经定义了这个 shell 函数:

f() { find . -name "*$1*"; }

注意:上面的行可以直接粘贴到 shell 中,也可以添加到用户的 ~/.bashrc 文件中。

然后,我可以通过键入以下命令来查找任何文件:

f some_name

或者,您可以使用具有简单语法的 fd 实用程序,例如 .fd pattern

评论

1赞 Broncha 6/8/2017
这只是进入一个级别。没有为我递归到子目录
4赞 kenorb 6/8/2017
@Broncha 因为您需要通过命令激活扩展通配。这在 Bash、zsh 和类似的 shell 中受支持。shopt -s globstar
0赞 drewish 10/17/2017
bash-3.2$ shopt -s globstarbash: shopt: globstar: invalid shell option name
0赞 kenorb 10/17/2017
@drewish 您需要将 Bash 升级到 4.x
77赞 toddcscar 1/14/2017 #5
find -L . -name "foo*"

在少数情况下,我需要 -L 参数来处理符号目录链接。默认情况下,符号链接将被忽略。在这些情况下,这很令人困惑,因为我会将目录更改为子目录并查看与模式匹配的文件,但 find 不会返回文件名。使用 -L 可以解决该问题。find 的符号链接选项为 -P -L -H

评论

6赞 Ritesh 1/4/2018
L开关非常有帮助。很多时候,用户对底层目录一无所知,无论它们是软链接的还是普通的目录。因此,如有疑问,使用 L 选项总是好的。至少,它一直对我有帮助。
71赞 XYZ_Linux 2/5/2017 #6

find <directory_path>  -type f -name "<wildcard-match>"

在通配符匹配中,您可以提供要匹配的字符串,例如,*.c(对于所有 C 文件)。

评论

5赞 wilsotc 11/23/2017
您的答案在这里是第一个最正确的,因为它只搜索指定的文件。其他未指定 type 的将返回目录。
1赞 XYZ_Linux 9/11/2019
如果您想搜索目录,“-type f”可以更改为“-type d”
0赞 M Imam Pratama 5/17/2022
默认情况下,检测符号文件链接(但不检测符号目录链接中的链接)。 将导致无法检测到符号文件链接。如果还想包含指向文件的符号链接,请使用 -L: 。不要使用,因为它还将包含符号目录链接。find-type ffindfind -L <optional_directory_path> -type f-type f,l
14赞 Alberto 5/31/2017 #7

用于文件搜索

find / -xdev -name settings.xml→整个计算机
→当前目录及其子目录
find ./ -xdev -name settings.xml

对于扩展名类型的文件:

find . -type f -name "*.iso"
19赞 Aleksandar Pavić 8/9/2017 #8

以递归方式搜索文件的默认方法是,在大多数情况下可用

find . -name "filepattern"

它开始递归遍历您所在位置中的文件名或模式。使用 find 命令,您可以使用通配符和各种开关。若要查看选项的完整列表,请键入

man find

或者,如果手册页在您的系统中不可用:

find --help

但是,还有比 find 更现代、更快的工具,它们遍历整个文件系统并索引文件。一种常见的工具是定位或定位/定位。您应该查看操作系统的手册以了解如何安装它,安装后,它需要启动数据库。如果安装脚本不适合您,可以通过键入

sudo updatedb

并且,要使用它来查找某些特定文件,请键入:

locate filename

或者,要从当前目录中查找文件名或模式,可以键入:

pwd | xargs -n 1 -I {} locate "filepattern"

它将查看其文件数据库,并快速打印出与您键入的模式匹配的路径名。 要查看位置选项的完整列表,请键入:或locate --helpman locate

此外,您可以将 locate 配置为通过 cron 作业在计划时间更新其数据库,因此在凌晨 1 点更新数据库的示例 cron 如下所示:

0 1 * * * updatedb

这些 cron 作业需要由 root 配置,因为 updatedb 需要 root 权限才能遍历整个文件系统。

19赞 user8848899 10/30/2017 #9

您可以使用:

find . -type f  -name 'text_for_search'

如果要使用正则表达式,请使用:-iname

find . -type f  -iname 'text_for_search'
8赞 Saman Bayat 2/5/2018 #10

如果要使用通配符搜索特殊文件,可以使用以下代码:

find . -type f -name "*.conf"

假设您想从这里搜索每个 .conf 文件:

.表示从这里开始的搜索(当前位置)表示此处为文件 (F)
的搜索项类型。
表示您要搜索具有 *.conf 名称的文件。
-type-name

评论

2赞 questionto42 8/31/2021
投反对票。这些应该是 2011 年接受的答案下的评论或编辑。
104赞 kenorb 6/13/2018 #11

fd

如果速度太慢,请尝试使用该实用程序 - 一种简单快捷的替代方法,可以替代用 Rust 编写。findfdfind

语法:

fd PATTERN

演示:

主页: https://github.com/sharkdp/fd

9赞 MukeshKoshyM 8/18/2018 #12

以下命令有助于搜索任何文件

  1. 无论情况如何
  2. 结果排除未经权限文件夹
  3. 从根目录或您喜欢的路径搜索。使用您喜欢的路径更改/。

语法:

find <FromDirectory> -iname '<FileName wild char allowed>'   2>&1 | grep -v "Permission denied"

find / -iname 'C*.xml' 2>&1 | grep -v "Permission denied"

评论

5赞 phuclv 3/23/2019
你到底为什么要用 grep 来做这件事?只需将 stderr 重定向到 nullfind / -iname '*C*.xml' 2>/dev/null
13赞 Anshul Singhal 11/27/2018 #13

以下命令将列出当前文件夹及其子文件夹中具有确切名称“pattern”(例如)的所有文件。

find ./ -name "pattern"

评论

2赞 questionto42 8/31/2021
投反对票。这重复了 2017 年的答案
1赞 EvgenKo423 5/28/2022
@Brian 新的答案有望提供一些新的信息或替代解决方案,重复已经说过的话是没有用的。就像问问题一样,在写答案之前,你应该先搜索,以确保你的答案会添加一些有用的东西。特别是当有很多其他答案时,在这种情况下,这种可能性接近 0。一点也不难,只需一个Ctrl+F。
0赞 Brian Wiley 5/28/2022
是的,你是对的。我现在同意,我想得更多了。
10赞 Jay Yang 2/22/2019 #14

这将搜索当前目录和子目录中的所有相关文件,分别计算它们的行数,以及全部计算它们的行数:

find . -name "*.wanted" | xargs wc -l
14赞 melchi 11/11/2019 #15

我很惊讶地发现,当我们要递归时,locate 并没有被大量使用。

我会先做一个定位“$PWD”来获取当前感兴趣的文件夹中的文件列表,然后根据需要对它们运行 greps。

locate "$PWD" | grep -P <pattern>

当然,这是假设 updatedb 已经完成并且索引会定期更新。这是查找文件的方法,比运行查找并要求它下树要快得多。为了完整起见,提到这一点。如果树不是很重,就不反对使用 find。

评论

2赞 Jefferey Cave 5/15/2020
locate "$PWD*.mp4"只是为了提醒您,您可以跳过grep
43赞 Shital Shah 1/15/2020 #16

find path/to/dir -name "*.ext1" -o -name "*.ext2"

解释

  1. 第一个参数是要搜索的目录。
  2. 默认情况下,执行递归。find
  3. 代表 .所以上面意味着搜索这个通配符或这个通配符。如果您只有一个模式,则不需要 .-o-or-o
  4. 通配符模式周围的引号是必需的。
-6赞 Katu 2/10/2021 #17

使用 Python>3.5,使用 glob,指向当前文件夹并查找文件:..txt

 python -c "import glob;[print(x) for x in glob.glob('./**/*txt', recursive=True)]"

对于旧版本的 Python,可以安装 glob2

评论

3赞 EvgenKo423 11/12/2021
有人可以解释一下反对票吗?如果我的回答有问题,我想知道它是什么。– 这个问题询问了 Linux shell 的原生解决方案,您用 Python 提供了答案。所以你的答案在这里是题外话。
0赞 Valerio Bozz 11/16/2021
我不明白你@EvgenKo423评论的部分内容,因为这个答案是由 Katu 而不是你回答的。
1赞 EvgenKo423 11/17/2021
@ValerioBozz 查看修订历史记录。我引用了他们的问题并回答了它。
1赞 EvgenKo423 1/19/2022
我看到了很多关于 sed 的问题,其中包含使用 awk 和类似问题的公认答案。[...]感觉这是被追随趋势而不是思考它的人投了反对票。– 但两者都是命令行工具,而 Python 是一种功能齐全的编程语言。否决答案会花费代表,这不鼓励无缘无故地这样做,但如果您仍然认为这是投票欺诈,请阅读这篇文章。P.S.:请使用评论或 Stack Overflow Chat 进行讨论,它们不属于答案。sedawk
8赞 Robert Ranjan 8/29/2021 #18

如果已安装,请尝试使用该命令。安装说明fd

查找所有以“name”开头的文件:

fd "name*"

此命令忽略所有和 ed 文件。.hidden.gitignore

要包含 ed 文件,请添加如下选项:.gitignore-I

fd -I "name*"

要包含隐藏文件,请添加以下选项:-H

fd -H "name*"
0赞 jian 9/4/2022 #19

您也可以使用 ripgrep

例:

搜索所有文件名包含子字符串 psql

rg --files | rg psql