I'd been playing with this snippet and seems like I can't make my desired find
work. I tried google but all tutorials does not seem to tackle this scenario
suppose i have the following files
test-[done].mkv
test.mkv
test2.avi
test3.mp4
what i want is for my find
to select all .mkv OR .avi OR .mp4
BUT NOT those with [done]
on its name
the first condition can be easily solve using
find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) -print
but I am having trouble doing the second condition, trying
find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) ! \( ! -name '*[done]*' \) -print
still shows the `test-[done].mkv
test-[done].mkv
test.mkv
test2.avi
test3.mp4
trying regex because I thought there's limit to how many -name can be used, but still no luck
[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
Can somebody please help me how to work on this? Thanks!
Best Answer
For your
-name
version, instead of! -name '*[done]*'
you need! -name '*\[done\]*'
- otherwise it's taking the letters in brackets as a character set, and thus excluding anything that includes the letter "d" or "o" or "n" or "e" (and all of your filenames contain "e"). You were then negating that condition a second time, so that rather than excluding all files it includes all files - but a corrected version would be:Your regex version is wrong because you have the
$
immediately after the pattern matching[done]
, but in your real file name there's still a file extension after that point - but adding a.*
before the$
does work.