remove certain files except others

I found so many suggestions as to how to remove files with exceptions. However, this case is a little different. Let's say, I have 6 files as follows in my Ubuntu 18.04:

text_1.json
text_2.json
video_1.mp4
video_2.mp4
video_1_notouch.mp4
video_2_notouch.mp4

The command should remove only video_1.mp4 and video_2.mp4 files while leaving other files as is.

I tried rm -v !(*.json|*_notouch.mp4) as suggested here, but it removed all 6 files.


Solution 1:

It is better and easier to use the find command:

find . -type f -name "*.mp4" ! -name "*_notouch.mp4" -exec rm -v {} \;

This command will match any file name ending with .mp4, but not with _notouch.mp4 and will run the command given after -exec.

Before such destructive operations, it always wise to prepend or replace the rm command with an echo and verify you are getting the commands you are expecting:

find . -type f -name "*.mp4" ! -name "*_notouch.mp4" -exec echo rm -v {} \;

[Edit] As mentioned in the comments; in your case, you can just use -print -delete in place of -exec echo rm -v {} \; (which will be more efficient if you have millions of files). And to list the files that will be affected (before running the destructive command) you can just run:

find . -type f -name "*.mp4" ! -name "*_notouch.mp4" (-print is optional)

Also, if you do not want to affect subdirectories, you can use the -maxdepth 1 option like this:

find . -maxdepth 1 -type f -name "*.mp4" ! -name "*_notouch.mp4".