我正在尝试查找任何名为 的文件dork
,但我想排除名为 的文件dork.zip
。我还删除了目录权限中的所有错误。
所以我这样编写命令:
find / -name "dork*" -and !"zip" 2>&1 | grep -iv "not"
这并没有像我预期的那样工作。
答案1
find / -name 'dork*' ! -name '*.zip'
您需要使用两个-name
测试。一种用于匹配dork*
,一种用于匹配*.zip
。其中第二个应该反转(!
),以便找到的名称与其不匹配。测试之间始终存在隐式 AND。
使隐式 AND 可见:
find / -name 'dork*' -a ! -name '*.zip'
还使用非标准 GNU 语法:
find / -name 'dork*' -and -not -name '*.zip'
要忽略由此产生的错误,请将标准错误流重定向到末尾的/dev/null
with 。2>/dev/null
使用 GNU,find
您可以选择不输入不可读的目录:
find / \( -type d -not -readable -prune \) -or \
\( -name 'dork*' -not -name '*.zip' -print \)
答案2
您误解了表达式的语法find
。我认为您期望测试按照其寻找的模式-name
进行处理,但期望"dork*" -and !"zip"
-name
单个模式字符串,而不是某种表达。解析它的方法find
是:(名称匹配dork*
)和(!zip
),!zip
是与主表达式分开的子表达式-name
。但这!zip
不是有效的表达式,因此您会收到错误。
您想要更像 (名称匹配dork*
) 和 (名称不匹配*.zip
) 的内容。
find / -name "dork*" -and '!' -name "*.zip"
(-and
实际上并不需要;为了清楚起见,我将其留在这里。)
我在这里做了一些其他更正:模式是*.zip
,因为zip
只会匹配名为的文件确切地“压缩”。!
由空格分隔,以便将find
其识别为单独的元素,而不是其他元素的一部分,并且我用单引号引用了它,因此如果您以交互方式使用该命令,shell 不会尝试将其解释为历史引用。
2>&1 and
顺便说一句, grep -iv“not”是怎么回事?如果您尝试过滤错误消息,并且使用的是 bash(而不是其他 shell),则可以使用命令替换来避免混合输出和错误流:
find / -name "dork*" -and '!' -name "*.zip" 2> >(grep -iv "not" >&2)