在 find 命令中排除目录范围
Exclude range of directories in find command
我有一个名为 test
的目录,其中包含 01
、02
、...31
等日期范围内的子文件夹。这所有子文件夹中都包含 .bz2 文件。我需要使用 find 命令搜索扩展名为 .bz2 的所有文件,但不包括特定范围的目录。我知道 find . -name ".bz2" -not -path "./01/*"
,但是如果我想跳过 10 个目录,写 -not -path "./01/*"
会很可怜。那么如何在 find
命令中跳过 01..19
子目录?
您可以在选项模式中使用通配符 -not -path
:
find ./ -type f -name "*.bz2" -not -path "./0*/*" -not -path "./1*/*
这将排除所有以 0 或 1 开头的目录。甚至更好:
find ./ -type f -name "*.bz2" -not -path "./[01]*/*"
首先,您可以使用 -prune
而不是 -not -path
来帮助 find
- 这甚至可以避免查看相关目录。
关于您的要点 - 您可以为您的示例构建一个通配符(数字 01 到 19):
find . -path './0[1-9]' -prune -o -path './1[0-9]' -prune -o -print
如果您的范围不太方便(例如 05 到 25),您可能希望将范围构建到 bash 变量中,然后将其插入到 find
命令中:
a=("-path ./"{05..25}" -prune -o")
find . ${a[*]} -print -prune
(您可能想 echo "${a[*]}"
或 printf '%s\n' ${a[*]}
看看它是如何工作的)
对我来说,我发现 find 命令作为一个独立的工具有点麻烦。因此,我总是最终使用 find 的组合来进行递归文件搜索和 grep 来制作实际的 exculsion/inclusion 东西。最后,我将结果移交给第三个命令,该命令将执行操作,例如 rm 以删除文件。
我的通用命令看起来像这样:
find [root-path] | grep (-v)? -E "cond1|cond2|...|condN" | [action-performing-tool]
- 根路径是递归开始搜索的地方
- 添加-v选项用于反转匹配结果
- cond1 - condN,匹配的条件。当涉及 -v 时,这是不匹配的条件。
- 动作执行工具完成实际工作
例如,您想要删除所有不匹配当前目录中某些条件的文件:
find . -not -name "\." | grep -v -E "cond1|cond2|cond3|...|condN" | xargs rm -rf
如你所见,我们是在当前目录中以点号为root-path:搜索,然后我们要反转匹配结果,因为我们要的是所有文件not 匹配我们的条件:最后我们将找到的所有文件传递给 rm 以便删除它们:我将 -rf 添加到 recursive/force 删除所有文件。我使用带有 -not -name "." 的 find 命令来排除通常由点指示的当前目录。
对于实际问题:假设我们有一个使用 .git 和 .metadata 目录的目录,我们想在搜索中排除它们:
find . -not -name "\." | grep -v -E ".git|.metadata" | [action-performing-tool]
希望对您有所帮助!
如果您想排除父目录下的子目录,那么这可能会有用:
例如-您有父目录 "ParentDir" 并且它有两个子目录 "Child1, Child2"。您只想从 "Chiled2" 读取文件并跳过 "Child1"。那么这将有所帮助。
find ./ParentDir ! -path "./ParentDir/Child1*" -name *.<extention>
我有一个名为 test
的目录,其中包含 01
、02
、...31
等日期范围内的子文件夹。这所有子文件夹中都包含 .bz2 文件。我需要使用 find 命令搜索扩展名为 .bz2 的所有文件,但不包括特定范围的目录。我知道 find . -name ".bz2" -not -path "./01/*"
,但是如果我想跳过 10 个目录,写 -not -path "./01/*"
会很可怜。那么如何在 find
命令中跳过 01..19
子目录?
您可以在选项模式中使用通配符 -not -path
:
find ./ -type f -name "*.bz2" -not -path "./0*/*" -not -path "./1*/*
这将排除所有以 0 或 1 开头的目录。甚至更好:
find ./ -type f -name "*.bz2" -not -path "./[01]*/*"
首先,您可以使用 -prune
而不是 -not -path
来帮助 find
- 这甚至可以避免查看相关目录。
关于您的要点 - 您可以为您的示例构建一个通配符(数字 01 到 19):
find . -path './0[1-9]' -prune -o -path './1[0-9]' -prune -o -print
如果您的范围不太方便(例如 05 到 25),您可能希望将范围构建到 bash 变量中,然后将其插入到 find
命令中:
a=("-path ./"{05..25}" -prune -o")
find . ${a[*]} -print -prune
(您可能想 echo "${a[*]}"
或 printf '%s\n' ${a[*]}
看看它是如何工作的)
对我来说,我发现 find 命令作为一个独立的工具有点麻烦。因此,我总是最终使用 find 的组合来进行递归文件搜索和 grep 来制作实际的 exculsion/inclusion 东西。最后,我将结果移交给第三个命令,该命令将执行操作,例如 rm 以删除文件。
我的通用命令看起来像这样:
find [root-path] | grep (-v)? -E "cond1|cond2|...|condN" | [action-performing-tool]
- 根路径是递归开始搜索的地方
- 添加-v选项用于反转匹配结果
- cond1 - condN,匹配的条件。当涉及 -v 时,这是不匹配的条件。
- 动作执行工具完成实际工作
例如,您想要删除所有不匹配当前目录中某些条件的文件:
find . -not -name "\." | grep -v -E "cond1|cond2|cond3|...|condN" | xargs rm -rf
如你所见,我们是在当前目录中以点号为root-path:搜索,然后我们要反转匹配结果,因为我们要的是所有文件not 匹配我们的条件:最后我们将找到的所有文件传递给 rm 以便删除它们:我将 -rf 添加到 recursive/force 删除所有文件。我使用带有 -not -name "." 的 find 命令来排除通常由点指示的当前目录。
对于实际问题:假设我们有一个使用 .git 和 .metadata 目录的目录,我们想在搜索中排除它们:
find . -not -name "\." | grep -v -E ".git|.metadata" | [action-performing-tool]
希望对您有所帮助!
如果您想排除父目录下的子目录,那么这可能会有用:
例如-您有父目录 "ParentDir" 并且它有两个子目录 "Child1, Child2"。您只想从 "Chiled2" 读取文件并跳过 "Child1"。那么这将有所帮助。
find ./ParentDir ! -path "./ParentDir/Child1*" -name *.<extention>