Deleting all files in a folder except files X, Y, and Z

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

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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

Method 2

Using zsh, with setopt EXTENDED_GLOB, using the ~ operator (except)

rm -- *~(x|y|z)

or ^ operator (negation):

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.

Method 3

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

Method 4

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.

Method 5

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

Method 6

It will delete all (including hidden) except selected files/folders in the CURRENT directory.

find . -maxdepth 1 ! -name "file1.php" ! -name "file2.js" ! -name "dir1" ! -name "dir2" ! -name . -exec rm -r {} ;

Method 7

This is what I set up as a .sh script for an OSX/MacOS logout hook, works well enough.

#! /bin/bash
for dir in /PathToFolder/*
 do
    if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then 
      echo ${dir}
      sudo rm -R $dir user
      dscl . -delete $dir
    fi 
  done

exit 0

Method 8

With GNU-find you can use the -delete switch, which removes directories, if empty, too:

 find tmp -not -name X -not -name Y -not -name Z -delete


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x