如何从Bash find命令的搜索路径中排除Mac Package文件?
macOS包含一些实际上是unix目录的“文件”。这些被称为“包装”。 Mac应用程序文件是一个很好的例子,但还有其他例子。不幸的是,我没有找到任何排除软件包的查找开关。
这是一个不起作用的典型find命令。它将在.app文件中搜索:
find /Applications -type f -path ./*.app -prune -o -print
在这种情况下,我希望它列出实际的.app文件,但不要在其中搜索。
我尝试了很多这种变化,但都没有奏效。
以下是一些其他确实是软件包的典型文件扩展名:
.app .pkg .scptd
答案 0 :(得分:1)
插入一个正则表达式条件,该条件对于包目录中的所有内容返回false。不幸的是,这确实意味着必须列出要排除其内容的软件包目录的文件扩展名。我已经在我的正则表达式字符串中列出了很多:
find -E /Applications ! -iregex '.*\.(app(download)?|scptd|pkg|bundle|qlgenerator|c?action|dictionary|cannedSearch|photoslibrary)/.+'
答案 1 :(得分:0)
尝试一下。我从另一个答案(来自用户anonymous-coward)获得了捆绑测试。将其放入一个小脚本中,并命名为“ bundle”,如下所示:
#!/bin/bash
content_tree=$(mdls -name kMDItemContentTypeTree "$@" | grep -E '\"com.apple.bundle\"')
[[ ! -z "$content_tree" ]] && exit 0 || exit 1
(随时改进我的bash。)如果自变量是束的路径,则束返回0(成功),否则返回1。它生成一些特定于Mac的元数据,并查找包特征。如果您想更具体地避免使用包而不是其他种类的捆绑包,则可以查找“ com.apple.package”。您的bundle
脚本可以选择所需的任何内容。在某些文件上运行mdls -name kMDItemContentTypeTree
,看看会出现什么,这将告诉您将什么正则表达式传递给grep
。您可以对文件扩展名等进行其他测试。然后像这样形成您的find
命令:
find /Applications \( -exec bundle {} \; -print -prune \) -or -print
我刚刚使用Applications
是因为它是一个示例,您可以在其中找到许多捆绑包和包装。如果外壳程序结果不为0,-exec
标签将返回false(因为0始终表示“成功”作为外壳程序结果)。因此,-or
左侧的表达式表示如果某事物是捆绑包,我们将打印其完整路径,而-prune
则表示我们不会继续进入目录。 -print
右边看似多余的-or
是因为如果您使用-exec
或其他一些运算符,find
将禁止所有打印,因此,如果出现以下情况,则需要打印路径它是一个包(或包或您的脚本检测到的任何东西),如果没有,则还会打印路径。注意:在测试结束后\;
和+
之前使用-print
而不是-prune
是关键。否则,find
会将大量文件分组以传递给bundle
,并且您需要为每个文件获得一个答案。您可以在-print
的任一侧或两侧将-exec
运算符替换为-or
,以防以某种方式处理文件而不仅仅是查找文件。原来,这是您要不同处理的任何两类文件的示例。希望这是有用的。这是一个有趣的练习,实际上在思考find
及其应用方面非常有用。
答案 2 :(得分:0)
要与 @cycollins 很好的答案相吻合,以下是辅助脚本的另一种形式(以及否定的味道),它更加简洁:
将此保存为 is_bundle
在您的$PATH
中的某个地方:
#!/usr/bin/env bash
mdls -name kMDItemContentTypeTree "$1" | egrep -q '\"com.apple.(bundle|package)\"'
,并将其另存为 is_not_bundle
:
#!/usr/bin/env bash
mdls -name kMDItemContentTypeTree "$1" | egrep -q '\"com.apple.(bundle|package)\"'
[ $? -eq 0 ] && exit 1 || exit 0
以下是一些用法示例:
仅查找包含<pattern>
(完全省略捆绑软件)的目录
find -s . -type d -iname "*pattern*" -exec is_not_bundle {} \; -print
查找包含<pattern>
的任何东西-不要分成束:
find -s . -iname "*pattern*" \( -exec is_bundle {} \; -print -prune -or -print \)
查找目录或捆绑包(但不要进入捆绑包)
find -s . -type d -mindepth 1 \( -exec is_bundle {} \; -print -prune -or -print \)
仅查找 个捆绑包
find -s . -type d -exec is_bundle {} \; -print -prune
查找与<pattern>
匹配的捆绑商品
find -s . -iname "*pattern*" -exec is_bundle {} \; -print -prune