【问题标题】:Recursively find all files that match a certain pattern递归查找与特定模式匹配的所有文件
【发布时间】:2014-04-21 23:47:05
【问题描述】:

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

*/foo/*.doc

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

【问题讨论】:

  • 必须是 bash 吗? zsh 可以使用 ls **/foo/*.doc 语法来做到这一点。
  • 阿拉斯泰尔,感谢您的建议。我不知道 zsh 及其双星号语法。有趣的是,生成的扩展参数列表对于 ls 来说似乎太长(大约 6000 个文件名)并给出了错误。
  • Bash v4 还支持** 递归全局。
  • echo 这样的内部命令避免了ARG_MAX 问题(参数列表太长)。 You should not be using ls in scripts.
  • @tripleee Bash v4 支持 ** 递归 glob,但您必须首先使用 shopt -s globstar。见tiswww.case.edu/php/chet/bash/bashref.html#The-Shopt-Builtin

标签: macos bash command-line


【解决方案1】:

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

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

只计算文件的数量:

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

(%i格式代码导致find打印inode编号而不是文件名;与文件名不同的是,inode编号保证没有换行符之类的字符,所以计数更可靠。感谢@三人组的建议。)

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

【讨论】:

  • 在最后加上“| wc -l”就完美了。
  • -printf '0\n' 怎么样?我们根本不需要 inode。
【解决方案2】:

怎么样:

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”的结果,因为这也会显示这些结果。

【讨论】:

  • 这行得通,只是它不适用于 BASE_OF_SEARCH 和 foo 之间的可变子目录深度。也许我对那个规范不够清楚。尽管我能够完成我打算完成的任务,但它已经足够接近了,因此请点赞并感谢您。
  • 你应该强调它不是递归的。然而,这通常是不需要的。那么这是一个简单而好的解决方案。虽然它可能存在性能问题 - 不知道。
  • 我为您的请求添加了一项功能
【解决方案3】:

根据此页面上其他页面上的答案,我设法将以下内容放在一起,在当前文件夹及其下的所有其他文件夹中执行搜索,以查找所有扩展名为 pdf 的文件,然后过滤标题中包含 test_text 的内容。

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

【讨论】:

【解决方案4】:

未经测试,但尝试:

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

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

【讨论】:

  • while 循环是完全冗余的并且有点容易出错。此外,通配符不会被扩展,因为它被引用了。只需将find -print 传送到wc -l。但是,如果文件名包含换行符,这仍然会给出错误的计数。
猜你喜欢
  • 1970-01-01
  • 2012-02-29
  • 2017-10-27
  • 2017-07-26
  • 1970-01-01
  • 2011-04-09
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多