Linux delete all files but one

How to delete all files in a directory except some?

I need to delete all files in a directory, but exclude some of them. For example, in a directory with the files a b c . z , I need to delete all except for u and p . Is there an easy way to do this?

The answers below are a lot better, but you could just make the files to save read-only, delete all, and then change them back to their original permissions (as long as you don’t use rm -f). You’d have to know what permissions to restore and you’d have to know that nothing needed write access to them during the process. This is why the other answers are better.

17 Answers 17

What I do in those cases is to type

Then I press Ctrl + X , * to expand * into all visible file names.

Then I can just remove the two files I like to keep from the list and finally execute the command line.

@SantoshKumar: That doesn’t make sense to me. The expansion will always work, it doesn’t depend on what command you want to use afterwards.

@OliverSalzburg Sorry, the combination is little bit confusing. I think you should write like Ctrl + Shift + x + *

To rm all but u,p in bash just type:

This requires the following option to be set:

You need to shopt -s extglob , @Ashot. Also, it’s just files, not directories, which is why I’ve removed the -rf options in your command.

If you need to exclude one file of a selection of files, try this: rm !(index).html . This will delete all files ending in «.html» with the exception of «index.html».

find . ! -name u ! -name p -maxdepth 1 -type f -delete 
  • ! negates the next expression
  • -name specifies a filename
  • -maxdepth 1 will make find process the specified directory only ( find by default traverses directories)
  • -type f will process only files (and not for example directories)
  • -delete will delete the files

You can then tune the conditions looking at the man page of find

  • Keep in mind that the order of the elements of the expressions is significant (see the documentation)
  • Test your command first by using -print instead of -delete
find . ! -name u ! -name p -maxdepth 1 -type f -print 

Источник

3 Ways to Delete All Files in a Directory Except One or Few Files with Extensions

Sometimes you get into a situation where you need to delete all files in a directory or simply cleanup a directory by removing all files except files of a given type (ending with a particular extension).

In this article, we will show you how to delete files in a directory except certain file extensions or types using rm, find and globignore commands.

Before we move any further, let us start by briefly having a look at one important concept in Linux – filename pattern matching, which will enable us to deal with our issue at hand.

In Linux, a shell pattern is a string that consists of the following special characters, which are referred to as wildcards or metacharacters:

  1. * – matches zero or more characters
  2. ? – matches any single character
  3. [seq] – matches any character in seq
  4. [!seq] – matches any character not in seq

There are three possible methods we shall explore here, and these include:

Delete Files Using Extended Pattern Matching Operators

The different extended pattern matching operators are listed below, where pattern-list is a list containing one or more filenames, separated using the | character:

  1. *(pattern-list) – matches zero or more occurrences of the specified patterns
  2. ?(pattern-list) – matches zero or one occurrence of the specified patterns
  3. +(pattern-list) – matches one or more occurrences of the specified patterns
  4. @(pattern-list) – matches one of the specified patterns
  5. !(pattern-list) – matches anything except one of the given patterns

To use them, enable the extglob shell option as follows:

1. To delete all files in a directory except filename, type the command below:

Delete All Files Except One File in Linux

2. To delete all files with the exception of filename1 and filename2:

Delete All Files Except Few Files in Linux

3. The example below shows how to remove all files other than all .zip files interactively:

Delete All Files Except Zip Files in Linux

4. Next, you can delete all files in a directory apart from all .zip and .odt files as follows, while displaying what is being done:

Delete All Files Except Certain File Extensions

Once you have all the required commands, turn off the extglob shell option like so:

Delete Files Using Linux find Command

Under this method, we can use find command exclusively with appropriate options or in conjunction with xargs command by employing a pipeline as in the forms below:

$ find /directory/ -type f -not -name 'PATTERN' -delete $ find /directory/ -type f -not -name 'PATTERN' -print0 | xargs -0 -I <> rm <> $ find /directory/ -type f -not -name 'PATTERN' -print0 | xargs -0 -I <> rm [options] <>

5. The following command will delete all files apart from .gz files in the current directory:

$ find . -type f -not -name '*.gz'-delete

Command find - Remove All Files Except .gz Files

6. Using a pipeline and xargs, you can modify the case above as follows:

$ find . -type f -not -name '*gz' -print0 | xargs -0 -I <> rm -v <>

Remove Files Using find and xargs Commands

7. Let us look at one additional example, the command below will wipe out all files excluding .gz , .odt , and .jpg files in the current directory:

$ find . -type f -not \(-name '*gz' -or -name '*odt' -or -name '*.jpg' \) -delete

Remove All Files Except File Extensions

Delete Files Using Bash GLOBIGNORE Variable

This last approach however, only works with bash. Here, the GLOBIGNORE variable stores a colon-separated pattern-list (filenames) to be ignored by pathname expansion.

To employ this method, move into the directory that you wish to clean up, then set the GLOBIGNORE variable as follows:

$ cd test $ GLOBIGNORE=*.odt:*.iso:*.txt

In this instance, all files other than .odt , .iso , and .txt files with be removed from the current directory.

Now run the command to clean up the directory:

Afterwards, turn off GLOBIGNORE variable:

Delete Files Using Bash GLOBIGNORE Variable

Note: To understand the meaning of the flags employed in the commands above, refer to the man pages of each command we have used in the various illustrations.

Thats all! If you have any other command line techniques in mind for the same purpose, do not forget to share with us via our feedback section below.

Aaron Kili is a Linux and F.O.S.S enthusiast, an upcoming Linux SysAdmin, web developer, and currently a content creator for TecMint who loves working with computers and strongly believes in sharing knowledge.

Each tutorial at TecMint is created by a team of experienced Linux system administrators so that it meets our high-quality standards.

Delete Huge Files in Linux

Parted Command in Linux

TLDR Man Pages for Linux Commands

apt-get Command Examples

Ubuntu apt-cache Commands

apt Command Examples

18 thoughts on “3 Ways to Delete All Files in a Directory Except One or Few Files with Extensions”

For me, the working method was “Delete Files Using Bash GLOBIGNORE Variable”. My goal was to leave only some video and audio files, independent of lower/uppercase: GLOBIGNORE=*.[Mm][Pp][34]:*.[Mm]4[Aa]:*.[Ww][Aa][Vv]:*.3[Gg][Pp]:*.[Mm][Oo][Vv]:*.[Oo][Gg][Gg]:*.[Oo][Pp][Uu][Ss]:*.[Aa][Aa][Cc]
rm -v *
unset GLOBIGNORE Hope this will help… Reply

Hi, I am trying to delete files from multiple directories through a shell script, in few directory files will come with an extension (.csv) and for few just an alphanumeric names. Now the problem is, for the files with the extension I am using below line of command and which is working as expected.

# find /Collected_Directory/A/ -type f -name '*.csv' -delete;

but for the directory having files without extension I am using the “rm” command as below which asks permission to delete each file.

  1. I can’t change the directory permission.
  2. I don’t want to delete any subdirectories as well.

Hello, thank you for removing my valuable files. At least make a note that your shopt method does NOT work for directories (e.g. rm -rfv !(“dirname”)) Reply

@Mekkanizer Oh sorry about losing your valuable files, but the heading/title is clear enough deleting of files with a particular extension. And the commands all show deleting of files e.g $ rm -v !(«filename») not directory name. Next time don’t try what is out of the scope a guide expecting the same results. Reply

A directory is a file, your understanding of Linux and your guide are both jokes. If you can’t make a guide clear then you either don’t understand what you are talking about or you are bad at explaining things. Next time, don’t try what you are not willing to do properly and learn before you teach. Thank you. Reply

If the directory contains sub-directories, which may or may not contain file/s of a particular extension, how to delete all other files recursively from the sub-directories as well, without deleting our file/s of particular extension. Reply

what is shopt -s extglob? and why can’t i able to delete without using this command like rm -v !(“*.gz”). Reply

Nice tips, thanks for that, my only concern is that, if you get anything wrong, you’ll delete the files you don’t want to delete… I would’ve thought it’d better to move the file you want to save elsewhere temporarily, and then remove all the files in the directory and replace the one(s) you want to keep… Reply

@Dave Welcome, and nice tip as well. Things may go wrong especially when you type a wrong command, as you have mentioned, it is always a good practice to do a backup before removing files. Reply

There probably should be some sort of saying that “two negative commands does not make for a positive result”, especially when you don’t have some undo method. So removing except for some kinds of files just seems a bit scary. Backing up before you do this seems like extra work. At any rate, I typically will try to find a nondestructive operation like ls to make sure something like this does what I want before I would even consider using rm. In particular, a nondestructive command that specifically lists what you will delete with rm the best. Maybe using mv first would be a good idea. Reply

@Greg Well said and its a good tip as you have explained here, however, cleaning up a directory by removing all files except a few would probably be a user’s intention. And before doing any removal of files, one must know why he/she is doing so, whether to remove old files of a particular type or just create more space on disk and so on. Lastly, the aim of the article is to provide a solution for a scenario where you can clear all files in a directory but need to leave those that end with a given extension. Reply

@djf Welcome and thanks for sharing your thoughts with us. We are always delighted to help our followers learn something new in Linux, as we also hope to learn from them. Reply

Curiously all tools (rm, find, shopt) and mainly concepts (GLOBIGNORE, wildcard) mentioned here comes from GNU project but you give all credit to the Linux project I think this is a not correct position about the GNU Project which deserve as credit as Linux Project. Reply

@sedlav This is a important concern in relation to support for F.O.S.S in general, we shall do as you have said in every future article. However, we have always given credit to both the Linux and GNU projects in the past. Reply

Источник

How to remove all but a few selected files in a directory?

I want to remove all files in a directory except some through a shell script. The name of files will be passed as command line argument and number of arguments may vary. Suppose the directory has these 5 files:

I want to remove two files from it through a shell script using file name. Also, the number of files may vary.

4 Answers 4

There are several ways this could be done, but the one that’s most robust and highest performance with large directories is probably to construct a find command.

#!/usr/bin/env bash # first argument is the directory name to search in dir=$1; shift # subsequent arguments are filenames to absolve from deletion find_args=( ) for name; do find_args+=( -name "$name" -prune -o ) done if [[ $dry_run ]]; then exec find "$dir" -mindepth 1 -maxdepth 1 "$" -print else exec find "$dir" -mindepth 1 -maxdepth 1 "$" -exec rm -f -- '<>' + fi 

Thereafter, to list files which would be deleted (if the above is in a script named delete-except ):

dry_run=1 delete-except /path/to/dir 1.txt 2.txt 

or, to actually delete those files:

delete-except /path/to/dir 1.txt 2.txt 

A simple, straightforward way could be using the GLOBIGNORE variable.

GLOBIGNORE is a colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion. If a filename matched by a pathname expansion pattern also matches one of the patterns in GLOBIGNORE, it is removed from the list of matches.

Thus, the solution is to iterate through the command line args, appending file names to the list. Then call rm *. Don’t forget to unset GLOBIGNORE var at the end.

#!/bin/bash for arg in "$@" do if [ $arg = $1 ] then GLOBIGNORE=$arg else GLOBIGNORE=$:$arg fi done rm * unset GLOBIGNORE 

*In case you had set GLOBIGNORE before, you can just store the val in a tmp var then reset it at the end.

Источник

Читайте также:  Loading operating system linux
Оцените статью
Adblock
detector