我一直在玩这个片段,似乎我无法完成我想要的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