题 递归查找与特定模式匹配的所有文件


我需要找到(或更具体地说,计算)与此模式匹配的所有文件:

* /富/ *。doc的

第一个通配符星号包含可变数量的子目录。


28
2018-04-21 23:47


起源


它必须是bash吗? zsh可以使用语法执行此操作 ls **/foo/*.doc。 - Alastair
阿拉斯泰尔,谢谢你的建议。我不知道zsh及其双星号语法。有趣的是,看起来生成的扩展参数列表对于ls(大约6000个文件名)来说太长了并且给出了错误。 - pw222
Bash v4也支持 ** 递归的glob。 - tripleee
像内部命令一样 echo 避免 ARG_MAX 问题(参数列表太长)。 你不应该使用 ls 在脚本中。 - tripleee
@tripleee Bash v4支持 ** 递归glob,但你必须先 shopt -s globstar。看到 tiswww.case.edu/php/chet/bash/bashref.html#The-Shopt-Builtin - BitwiseMan


答案:


使用gnu find你可以使用正则表达式(不像 -name)匹配整个路径:

find . -regex '.*/foo/[^/]*.doc'

要计算文件数量:

find . -regex '.*/foo/[^/]*.doc' -printf '%i\n' | wc -l

(该 %i 格式代码原因 find 打印inode编号而不是文件名;与文件名不同,inode编号保证不具有换行符等字符,因此计数更可靠。感谢@tripleee的建议。)

但我不知道这是否适用于OSX。


31
2018-04-22 00:03



将“| wc -l”附加到此末尾并且它是完美的。 - pw222
怎么样呢 -printf '0\n'?我们根本不需要inode。 - Cœur


怎么样:

find BASE_OF_SEARCH/*/foo -name \*.doc -type f | wc -l

这是做什么的:

  • 从目录BASE_OF_SEARCH开始/
  • 查看具有目录foo的所有目录
  • 查找名为* .doc的文件
  • 计算结果的行数(每个文件一行)

这种方法的好处:

  • 不是递归的也不是迭代的(没有循环)
  • 它很容易阅读,如果你把它包含在一个脚本中,它很容易破译(正则表达式有时不是)。

更新:你想要变深?好:

find BASE_OF_SEARCH -name \*.doc -type f | grep foo | wc -l

  • 从目录BASE_OF_SEARCH开始
  • 查找名为* .doc的文件
  • 只显示包含“foo”的结果行
  • 计算结果的行数(每个文件一行)

或者,您可以过滤掉文件名中包含“foo”的结果,因为这也会显示这些结果。


9
2018-04-21 23:54



除了它不能用于BASE_OF_SEARCH和foo之间的可变子目录深度这一事实之外,这是有效的。也许我对该规范不够清楚。尽管我已经能够完成我要完成的任务,但它足够接近,所以这是一个upvote并且谢谢你。 - pw222
你应该强调它不是递归的。但是,通常不需要这样做。那么这是一个简单而又好的解决方案。虽然它可能有性能问题 - 不知道。 - robsch
我已经为您的请求添加了一项功能 - MonkeyWidget


未经测试,但尝试:

find . -type d -name foo -print | while read d; do echo "$d/*.doc" ; done | wc -l

找到所有“foo”目录(在不同的深度)(这会忽略符号链接,如果这是你可以添加它们的问题的一部分);使用shell globbing查找所有“.doc”文件,然后计算它们。


2
2018-04-22 00:00



该 while 循环是完全冗余的并且有些容易出错。此外,通配符不会被扩展,因为它被引用。只是管道 find -print 至 wc -l。但是,如果文件名包含换行符,则仍会给出错误的计数。 - tripleee


基于此页面上其他页面上的答案,我设法将以下内容组合在一起,其中在当前文件夹中执行搜索,在其下的所有其他文件中对所有具有扩展名的文件执行搜索 PDF格式,然后对包含的那些进行过滤 test_text 他们的头衔。

find . -name "*.pdf" | grep test_text | wc -l

0
2018-04-30 13:42



我设法找到包含所有信息的答案的原始帖子 unix.stackexchange.com/questions/123440/... - Teo Tsisme