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.

I have a lot of files and folders in a specific folder and I want to delete all of them; however, I wanted to keep files X, Y, and Z.

Is there a way I can do something like: rm * | but NOT grep | X or Y or Z

share|improve this question
    
I assume I can use some regular expression in there that will do this? –  Amit Feb 10 '11 at 22:46
add comment

6 Answers

up vote 9 down vote accepted

Instead of using rm, it may be easier to use find. A command like this would delete everything except a file named exactly 'file'

find . \! -name 'file' -delete

Many versions of should be able to support globbing and regular expression matching.

You could also pipe the output of find to rm as well

find . \! -name '*pattern*' -print0 | xargs --null rm 
share|improve this answer
2  
And this lets you see exactly what files will be deleted by removing the -delete as well as what files will be saved by removing -delete and the \!. –  Shawn J. Goff Feb 11 '11 at 0:51
add comment

Using zsh, with setopt EXTENDED_GLOB

rm *~{x,y,z}

But, you should probably instead move the files elsewhere, then delete everything. It's far safer in terms of finger slips, such as hitting enter too soon.

share|improve this answer
    
+1 for your last paragraph –  glenn jackman Feb 11 '11 at 14:01
add comment

Later versions of bash have the extglob shell option that gives you a syntax for doing what you want (check your man page under "Pathname Expansion" to see if your installed version has it):

$ shopt -s extglob  # turn on extended globbing
$ rm !(X|Y|Z)

To test, I suggest you first replace rm with echo to see if the list of files to be deleted is what you expect.

share|improve this answer
add comment
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r

Attention: Run the command and if the files to be deleted are the right ones, run it again and delete the hash character "#".

If the filenames are more complicated then that, do

ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r

Again, first look at the results then remove the hash sign.

This version - as suggested in the comments - saves some characters and looks a bit clearer.

ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r
share|improve this answer
    
A suggested edit by ddeimeke is to change the egrep argument to "^(file1|filename2|f1le)$" –  Michael Mrozek Feb 11 '11 at 22:37
    
If you have three files a, b and a b the first program will delete - if you put ab into the grep part: "^[ab]$" a and b but not a b, just opposed to your intentions. The second command will do the same. And the third too. You shouldn't use 'ls' in scripts, with very, very rare exceptions. Just don't do it. –  user unknown Mar 12 '11 at 2:17
add comment

Move the files you want to keep away. Go up one level, delete the folder. Re-create the folder and move those files back.

share|improve this answer
    
I wonder why the minus?.. It's actually both easier and safer than anything proposed by others: you simply can't shoot yourself in a foot by hitting some special char in the filename. –  alex Feb 11 '11 at 8:34
    
a) You move your file X one directory up, where a file X exists - silently deleted, gone. b) You're in the top dir, where no 'up' exists. c) You're in your home, and don't have permission to write to /home. If you put your advice into a script, and tested it without problem, and use it in such a situation - peng! –  user unknown Mar 12 '11 at 2:38
1  
a) Hey, did I say 'move files up one level'? I've said move them away. b) So you're trying to remove all files in /, heh? Not very practical. c) Trying to remove all files in your $HOME isn't really practical either. –  alex Mar 12 '11 at 6:48
    
You're right, I'm sorry. –  user unknown Mar 12 '11 at 7:14
add comment
 find tmp -not -name X -not -name Y -not -name Z -delete 
share|improve this answer
    
If X, Y or Z is a directory, this will delete files inside them as well. find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -delete is one way to work around this. –  Gilles Mar 12 '11 at 1:00
    
Since folders under Unix are files (anything is a file), that's maybe what is intended. The question explicitly says: "I have a lot of files and folders in a specific folder and I want to delete all of them; " - and if you like to exclude Y, maybe you know whether Y is a directory or not. –  user unknown Mar 12 '11 at 1:37
add comment

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.