Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Can I modify the rm command with regular expression or something to delete. every file in current directory except files with extensions *.bmp, *.wav and *.png? It should be case insensitive because there are files like *.BMP or *.bMP.

share|improve this question
3  
mv all *.bmp, *.wav, *.png to newdir. Then rm -rf dir. –  kev Dec 27 '11 at 14:37

4 Answers 4

up vote 11 down vote accepted

@ChrisDown has given a bash solution that takes into account the difference of files and directories, and also if there is no file to remove.

Given that rm would fail however in these situations, the command could be simplified as (still with bash):

shopt -s extglob nocaseglob
rm -- !(*.bmp|*.wav|*.png)

Remember to reset the two shell options to their default values. In my case extglob is already set on interactive shells, so I only need

shopt -u nocaseglob

Or run those two commands in a subshell:

(shopt -s extglob nocaseglob
rm -- !(*.bmp|*.wav|*.png))

If you would like to see in advance what files will be removed, simply substitute the rm with echo.

If you would like hidden files to be removed as well, add the dotglob option.

share|improve this answer
    
@enzolib This is already out of the scope of the question, but I used commas instead of | and everything from the directory was deleted (nothing important, so I downloaded it again), but I can imagine the danger of this command. Is there some less severe command with possibility of backup? –  xralf Dec 28 '11 at 10:49
    
@enzolib I see you edited the question and your last sentence is very useful. –  xralf Dec 28 '11 at 10:51

If you are using bash, you can use a combination of extglob and nocaseglob.

shopt -s extglob nocaseglob
for file in !(@(*.bmp|*.wav|*.png)); do
    [[ -f "${file}" ]] && files+=( "${file}" )
done
(( ${#files[@]} )) && rm "${files[@]}"

Otherwise you can us something like the following:

find . -maxdepth 1 -type f ! \( -iname '*.bmp' -o -iname '*.wav' -o \
    -iname '*.png' \) -delete
share|improve this answer
2  
-exec rm {} can be replaced with -delete –  akond Dec 27 '11 at 14:42
    
Thank you for this complex command. Actually I was looking for something more simple, to be able to use it quickly, when I have a need. So enzolib's solution is more convenient for my common needs. –  xralf Dec 27 '11 at 17:16
    
@xralf Bear in mind that that will not only remove regular files, however... –  Chris Down Dec 27 '11 at 20:37
    
@ChrisDown That's quite strange, because I usually have to use rm -r to remove directories. –  xralf Dec 28 '11 at 10:54
    
@xralf It's not only directories that are not regular files. –  Chris Down Dec 28 '11 at 11:08

With zsh, to remove the regular files other than the .bmp, .png, .wav (case insensitively) ones:

setopt extendedglob # best in ~/.zshrc
rm -- *.^(#i)(png|bmp|wav)(D.)

(remove the D above if you want to preserve hidden files regardless of their extension).

share|improve this answer

I would suggest that you take a little time and do this in multiple steps so you do not do anything accidently silly.

  1. create a command to identify the files you want to delete, e.g.

        ls | grep -v *.bmp | grep -v *.wav  # current directory
    

    or

        find . -type f | grep -v *.bmp      # current and sub directories
    

    if the list of returned files is what you want to remove, then

  2. recall the last command and add the xargs rm command to it, e.g.

        ls | grep -v *.bmp | grep -v *.wav | xargs rm
    
share|improve this answer
2  
I don't understand why you consider using grep -v instead of find's inbuild ! -iname any safer. Not to mention that this doesn't work in a case-insensitive fashion as requested in the question, and will break on newlines. –  Chris Down Dec 27 '11 at 22:16
    
Not to mention that grep -v *.bmp doesn't make any sense, you probably meant grep -v '\.bmp$'. –  Stéphane Chazelas yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.