`查找` 多个 -o -name 条件 AND ! -姓名

`查找` 多个 -o -name 条件 AND ! -姓名

我一直在玩这个片段,似乎我无法完成我想要的find工作。我尝试过谷歌,但所有教程似乎都没有解决这种情况

假设我有以下文件

test-[done].mkv
test.mkv
test2.avi
test3.mp4

我想要的是我find选择所有.mkv OR .avi OR .mp4但不是那些[done]名字上有的

第一个条件可以很容易地解决

find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) -print

但我在执行第二个条件时遇到困难,尝试

find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) ! \( ! -name '*[done]*' \) -print

仍然显示`test-[done].mkv

test-[done].mkv
test.mkv
test2.avi
test3.mp4

尝试正则表达式,因为我认为可以使用多少个 -name ,但仍然没有运气

[root@xxxx]# ls
test-[done].mkv  test.mkv  test2.avi  test3.mp4
[root@xxxx]# find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) ! \( -regex '.*\(\[done\]\)$' \) -print
test-[done].mkv
test.mkv
test2.avi
test3.mp4

有人可以帮我解决这个问题吗?谢谢!

答案1

对于您的-name版本,而不是! -name '*[done]*'您需要的! -name '*\[done\]*'- 否则它将把括号中的字母作为字符集,从而排除包含字母“d”或“o”或“n”或“e”(以及您的所有文件名)的任何内容包含“e”)。然后,您第二次否定该条件,这样它就不会排除所有文件,而是包含所有文件 - 但更正后的版本将是:

find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) \( ! -name '*\[done\]*' \) -print

您的正则表达式版本是错误的,因为您$在模式匹配之后立即有[done],但在您的真实文件名中,该点之后仍然有一个文件扩展名 - 但.*在 之前添加 确实$有效。

find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) ! \( -regex '.*\(\[done\]\).*$' \) -print

相关内容