How to delete all files from Directory except specific files

I want to remove all the files from a directory except one or more files. We usually use rm -rf command to remove all the files, but the problem is that it will remove all the files, which we don’t want to do. 

You may say it’s simple just move the file to a specific location or make a zip of a particular file and delete the rest of the file. Yes, we can do it, but we have to run multiple commands, which I don’t want, and it is not optimal.

So, how do I remove all the files from a directory except one? Well, in this article, you will see multiple ways to remove all files while protecting the important files.

There are several ways to do this, but in this article, I will show you two of them.

All time rm command with negation

First and foremost, you need to enable extglob shell option. Otherwise, you may get the error “bash: !: event not found”.

To enable this, pass the below command.

$ shopt -s extglob

We will create a list of file names from /usr/share/dict/words for illustration purposes. After that, we will delete all the files except “discipline”. 

$ mkdir /tmp/sample && cd /tmp/sample 
$ xargs -d '\n' touch < /usr/share/dict/words

To delete all the files except “discipline”, then pass the following command.

$ rm -v !(discipline)
$ ls

  • rm: utility to remove files
  • v: print the actions
  • !(discipline): mention the file name that you don’t want to delete.

The above command will delete all the files except the specified file name and what to do next. If I want to reserve multiple files, For this task, you have to use | to add multiple file names.

To explain it better, see the below code.

$ rm -v !(discipline|zygote|Zulus)
$ ls

discipline  Zulus  zygote

The above command will delete all the files except “discipline|zygote|Zulus“.

You can use a wildcard globbing pattern to save multiple files. In the following example, I want to keep a file that starts with “Zw” and delete the rest of the file. 

$ rm -v !(Zw*)
$ ls

Zwingli  "Zwingli's"   Zworykin  "Zworykin's"

As you know rm command can be a disaster, So the best and safest way to delete your files is to use the -i option. This will prompt you before deleting each file, and you can decide whether you want to delete it or not.

rm -i !(*.txt)

If you want to retain a specific extension file then replace .txt and run the below code.

$ rm -v !(*.txt)
$ ls

sample.txt trendoceans.txt 

You should read:Learn about Virtual memory statistics using vmstat

Use Find Command to keep specific file and delete the rest

In the section, you will see how to use the find command to keep specific files and delete the rest.

The logic for removing a file is similar to the above method. Just the syntax is different. So, first, we will see the basic syntax, then we will move to the example.

$ find [PATH] -not -name '[FILE-NAME]' -delete
  • [PATH]: provide: a path where you want to run the following command.
  • -not: It is like a negation that you can even replace with !
  • -name: specify the filename or pattern.
  • -delete: delete the file except for the specified name.

Now you will see how to use the above syntax with the help of the below command. Can you guess the output?

$ find . -not -name 'discipline' -delete

Yes, all the files will be removed except for discipline.

Though I want to keep all the .pdf and .epub files, they should be present in a directory, and the rest of the files should be deleted.

$ find . -type f -not \( -name '*.epub' -o -name '*.pdf' \) -delete

The above command is best when you are looking to keep multiple files.

You should read: 20+ Find command which you can use daily

Wrap up

The above command makes our work pretty easy to organize directory in a proper way. If you are using the find command with a regex to delete a file then I advise you to use -print instead of delete for preview.

A bonus command you can use ls, grep, | and xargs to remove unwanted files.

$ ls | grep -v '[FILE-NAME]' | xargs rm

That’s all for now.

Leave a Reply