查找来自不同目录的文件,包括和排除某些文件

查找来自不同目录的文件,包括和排除某些文件

我想从三个不同的文件夹中查找包含和排除某些文件的文件。
文件夹 1:

  • 路径:/var/www/app/var/log/
  • 仅排除:file1.log 和 file2.log

文件夹 2:

  • 路径:/var/log/web/log/
  • 仅包含:error.log

文件夹 3:

  • 路径:/var/log/service/log/
  • 仅包括:app1.error.log 和 app2.error.log

在这种情况下,我该如何搜索来自三个不同文件夹的文件?

答案1

您可以使用 来实现这一点。阅读有关在排除和包含上下文中find的 的一般用法:find递归搜索具有排除和包含的文件

您的问题涉及三条路径,每条路径都有不同的要求。可以在一次调用中指定多个起点find并构建表达式(例如使用-path),以便对不同的路径执行不同的测试。这是可能的,但相当麻烦。一种简单的方法是按顺序运行三个单独的 find 命令。

find /var/www/app/var/log ! -name file1.log         ! -name file2.log
find /var/log/web/log       -name error.log
find /var/log/service/log   -name app1.error.log -o   -name app2.error.log

笔记:

  • 上述命令中的多个空格只是为了强调它们的结构和相似性。

  • 你说“我想查找文件”。上述命令将查找文件包括目录类型的文件;特别是第一个命令将找到自己的起点(…/log)。要查找常规文件,您只需要-type f。要查找非目录,您只需要! -type d

  • 如果file1.logapp1.error.log属于目录类型,则不清楚“包含”或“排除”是指单独的目录还是指目录及其下面的所有内容。这可能不是问题,因为file1.log这些很可能是设置中的常规文件。

    需要说明的是,上述每个命令都会遍历其起始点下的整个目录树。例如,如果file1.log是目录类型,则! -name file1.log不会停止find测试file1.log/foo。要排除子树,您需要-prune

  • find递归工作。使 GNUfind不进入子目录的最简单方法是-maxdepth 1。非 GNU 实现可能不支持它。使用纯 POSIXfind 事情没那么简单

    您已标记;Ubuntu 提供find开箱即用的 GNU,因此可以-maxdepth 1自由使用。

  • 正确使用-o 并不像你想象的那么简单

  • 如果涉及符号链接,请阅读 中的-H-L选项man 1 find。您可能想要使用其中之一。


考虑到所有这些,我可以制作第三个命令的示例变体,该命令或许更好地满足您的需求:

find /var/log/service/log/ -maxdepth 1 -type f \( -name app1.error.log -o -name app2.error.log \)

或者 POSIX-ly(为了让答案对一般观众更有用):

find /var/log/service/log/. \( -name . -o -prune \) -type f \( -name app1.error.log -o -name app2.error.log \)

后一个命令中起始点的最后一个部分以 结尾.。这允许我们使用通用解决方案(我的意思是形式-name . -o -prune不依赖于起始点路径的真正有意义的部分)。另一方面,find将在每个路径名中包含/.,您可能不想要这样。


运行三个find而不是一个并不会阻止您将结果传送到单个目的地(例如xargs):

{ find … ; find … ; find … ; } | xargs …

注意在 Ubuntu 中你可以执行find … -print0 | xargs -r0 …。这是更加坚固,但find … -print | xargs …不便携。

相关内容