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

joh*_*ohn 1695 linux shell

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

tux*_*21b 2477

使用find:

find . -name "foo*"
Run Code Online (Sandbox Code Playgroud)

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

  • `find`需要一个起点,而.(dot)正在选择当前目录.例如,如果你在/ home/myuser中,`find/home/myuser`和`find .`有相同的结果. (66认同)
  • 请注意,"foo*"在引号中,因此shell在将其传递给find之前不会展开它.如果你只是'找到了.foo*`,`foo*`将被扩展然后传递给find. (22认同)
  • 值得强调的是,""对于递归搜索非常必要. (21认同)
  • 我知道这被标记为linux但是值得一提的是:在其他不是linux的*nix变种上需要路径.在linux上,如果要使用点,则路径是可选的. (20认同)
  • @Seatter"foo*"告诉find查找以"foo"开头的所有文件.这只是他的榜样.您可以使用"gpio*"查找名称以gpio开头的所有文件,或只使用"gpio1"查找名为gpio1的所有文件. (4认同)
  • 使用 -iname 不区分大小写 (3认同)
  • 由于某种原因,它在放入 sh 脚本时不起作用。需要bash什么的吗? (2认同)
  • 也很有用:如果您不想被通知您没有权限(或其他错误)的目录,可以执行`find。-name“ foo *” 2> / dev / null` (2认同)
  • @WesternGun 你能解释一下为什么需要 `" "` 吗?什么是“扩张”,为什么那么糟糕? (2认同)
  • @KolobCanyon 您可以查看 find 的手册页,或 [此链接](https://linux.die.net/man/1/find) 并搜索“non-bug”一词,然后搜索“quote”,您就可以有更多信息。另外,检查 [this](http://linuxcommand.org/lc3_lts0080.php)。通常,`*` 扩展是“迭代当前目录并将 * 替换为每个文件名”。因此,为了避免这种情况,我们使用引号。 (2认同)
  • @KolobCanyon 类似的东西,但链接有更多,我认为扩展更广泛。 (2认同)
  • 如果我省略引号,它将仅在当前目录中搜索。这个天才设计师应该解释一下这种行为。 (2认同)
  • 请注意,有时子目录是符号链接的,要遍历这些子目录,您需要包含 -L 选项 (2认同)
  • 如果您只想要文件**而不需要目录**,请使用 [`-type f`](/sf/answers/2943686301/) (2认同)

Pau*_*ipp 205

管道找到grep往往更方便; 它为您提供了任意通配符匹配的正则表达式的全部功能.

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

~$ find . -print | grep -i foo
Run Code Online (Sandbox Code Playgroud)

  • `find`还具有`-iname`,`-regex`和`-iregex`标志,用于不区分大小写的通配符,正则表达式和不区分大小写的正则表达式匹配,因此不需要使用`grep`. (50认同)
  • 我不认为这是不必要的,但更方便. (5认同)
  • 但是,通过管道传递到 grep -v 可以让您使用简单的字符串或正则表达式来删除不需要的条目。 (3认同)
  • 这里一个重要的警告是,如果您在包含大量文件(例如“\”)的目录上使用 find,那么这可能会非常慢。 (3认同)
  • @iobender-很遗憾,我可以从经验中告诉您,并非所有系统都带有支持这些选项的`find`命令。有时,`grep`成为唯一的选择。 (2认同)

Isl*_*Cow 137

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

find . -name "*foo"
Run Code Online (Sandbox Code Playgroud)

但是,如果你想要一张照片:

tree -P "*foo"
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 没有安装"apt-get"的Mac OSX用户的"brew install tr​​ee" (14认同)
  • sudo yum install tr​​ee -y for CentOS (3认同)

tod*_*car 30

find -L . -name "foo*"
Run Code Online (Sandbox Code Playgroud)

在少数情况下,我需要-L参数来处理符号目录链接.默认情况下,将忽略符号链接.在那些情况下,它很混乱,因为我将目录更改为子目录并查看匹配模式的文件但查找不会返回文件名.使用-L解决了这个问题.find的符号链接选项是-P -L -H

  • L开关很有帮助。很多时候用户对底层目录没有任何概念,无论它们是软链接还是普通目录。因此,如有疑问,使用 L 选项总是好的。至少,它一直帮助我。 (3认同)
  • 这就是我的答案。谢谢! (2认同)

ken*_*orb 26

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

echo **/*foo*
Run Code Online (Sandbox Code Playgroud)

以递归方式查找任何文件或文件夹.这由Bash 4,zsh和类似的shell支持.


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

f() { find . -name "*$1*"; }
Run Code Online (Sandbox Code Playgroud)

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

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

f some_name
Run Code Online (Sandbox Code Playgroud)

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

  • @Broncha因为你需要通过`shopt -s globstar`命令激活扩展的globbing.Bash,zsh和类似shell支持此功能. (3认同)
  • 这只是进入一个级别。不为我递归到子目录 (2认同)

XYZ*_*nux 25

find <directory_path>  -type f -name "<wildcard-match>"
Run Code Online (Sandbox Code Playgroud)

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

  • 您的答案是第一个最正确的,因为它只搜索指定的文件。其他未指定类型的将返回目录。 (2认同)

ken*_*orb 21

fd

如果find太慢,请尝试fd实用程序 - find用Rust编写的简单快速的替代方法.

句法:

fd PATTERN
Run Code Online (Sandbox Code Playgroud)

演示:

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

  • 我第一次在近9年里看到了一个关于SO的GIF.不错的工作! (11认同)
  • 这些性能结果看起来非常有希望。您可能会考虑将 fd 添加到 home-brew ... (2认同)
  • @aprodan演示图像是从GitHub复制的,但是我相信他们正在使用[`asciinema`](https://asciinema.org/),然后转换为GIF格式,但是我不确定。 (2认同)

小智 10

您可以使用:

# find . -type f  -name 'text_for_search'
Run Code Online (Sandbox Code Playgroud)

如果你想使用REGX使用 -iname

# find . -type f  -iname 'text_for_search'
Run Code Online (Sandbox Code Playgroud)


Jay*_*ang 10

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

find . -name "*.wanted" | xargs wc -l
Run Code Online (Sandbox Code Playgroud)


Shi*_*hah 10

find path/to/dir -name "*.ext1" -o -name "*.ext2"
Run Code Online (Sandbox Code Playgroud)

解释

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


mel*_*chi 9

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

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

locate "$PWD" | grep -P <pattern>
Run Code Online (Sandbox Code Playgroud)

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

  • `locate "$PWD*.mp4"` 只是提醒您可以跳过 `grep` (2认同)

Rob*_*jan 8

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

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

fd "name*"
Run Code Online (Sandbox Code Playgroud)

此命令忽略 all.hidden.gitignoreed 文件。

要包含.gitignoreed 文件,请添加-I以下选项:

fd -I "name*"
Run Code Online (Sandbox Code Playgroud)

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

fd -H "name*"
Run Code Online (Sandbox Code Playgroud)


Ale*_*vić 7

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

find . -name "filepattern"
Run Code Online (Sandbox Code Playgroud)

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

man find
Run Code Online (Sandbox Code Playgroud)

或者您的系统上没有手册页

find --help
Run Code Online (Sandbox Code Playgroud)

但是,还有更多更现代,更快捷的工具可以遍历整个文件系统并为文件建立索引,其中一种常见工具是定位或定位/定位,您应该查看操作系统手册以了解如何安装它,安装后需要启动数据库,如果安装脚本不帮您完成,可以通过键入以下内容手动完成

sudo updatedb
Run Code Online (Sandbox Code Playgroud)

并且,使用它来查找某些特定的文件类型

locate filename
Run Code Online (Sandbox Code Playgroud)

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

 pwd | xargs -n 1 -I {} locate "filepattern"
Run Code Online (Sandbox Code Playgroud)

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

另外,您可以配置locate通过cron作业按计划的时间更新它的数据库,因此示例cron在1AM更新数据库的示例如下所示:

0 1 * * * updatedb
Run Code Online (Sandbox Code Playgroud)

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


Muk*_*hyM 6

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

1)
不考虑情况2) 结果 未经许可排除文件夹
3) 从根目录或您喜欢的路径搜索。更改 / 使用您喜欢的路径。

语法:
find -iname '' 2>&1 | grep -v "权限被拒绝"

示例

find / -iname 'C*.xml' 2>&1 | grep -v "权限被拒绝"

find / -iname '*C*.xml'   2>&1 | grep -v "Permission denied"
Run Code Online (Sandbox Code Playgroud)

  • 你到底为什么要使用 grep 呢?只需将 stderr 重定向到 null `find / -iname '*C*.xml' 2&gt;/dev/null` (3认同)

Alb*_*rto 5

用于文件搜索
find / -xdev -name settings.xml ->整个计算机
find ./ -xdev -name settings.xml ->当前目录及其子目录,

用于扩展名类型的文件

find . -type f -name "*.iso"
Run Code Online (Sandbox Code Playgroud)


Rez*_*ani 5

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

find . -type f -name "*.conf"
Run Code Online (Sandbox Code Playgroud)

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

.表示从这里开始搜索(当前位置)
-type表示这里是文件(f)的搜索项的类型。
-name意味着您要搜索具有*.conf名称的文件。

  • 投反对票。这些应该是[2011年接受的答案](/sf/answers/413354651/)下的评论或编辑。 (2认同)

ans*_*hul 5

Following command will list down all the files having exact name "pattern" (for example) in current and its sub folders.

find ./ -name "pattern"

  • 投反对票。这重复了[2017年的答案](/sf/answers/3099595201/)。 (2认同)