Delete All .log files execept for one

You can use find command, but be careful while using it - you might end up removing everything you have.

  • Important: First you have to run the command without the -delete option to make sure the output is what you want to delete. Notice that -name looks for exact filename.

    $ find -not -name mongodb.log -name "*.log"
    
  • If the output is proper and you're sure the command locates only the files we want to remove, then you have to add the -delete option to the END of the command.

    $ find -not -name mongodb.log -name "*.log" -delete
    

    The order of the options for find is significant, and in this case if -delete option is placed anywhere other than the end of the command - it will remove everything.

Example

Imagine we have these files:

$ ls
1.log  2.log  3.log  4.log  5.log  bar  foo  mongodb.log

Let's list all *.log excluding mongodb.log. Check the output and make sure it doesn't contain anything except log files.

$ find -not -iname mongodb.log -name "*.log"
  • Notice the -iname! to keep both upper and lowercase versions of mongodb.log.

Then remove them using:

$ find -not -iname mongodb.log -name "*.log" -delete

Check again and you will see the log files are gone as expected but mongodb.log remains there.

$ ls
bar  foo  mongodb.log

To delete all files except the one named mongodb.log, you can use extended globbing. First, enable the option:

shopt -s extglob

And then, you can run:

rm !(mongodb.log)

Or, to delete only files with a .log extension, but not mongodb.log, you can do:

rm !(mongodb).log

For example:

$ ls
file1  file2  file3.log  file4.log  file5.log  mongodb.log
$ rm !(mongodb).log
$ ls
file1  file2  mongodb.log

if you need this to be recursive, to match files in subdirectories as well, you can use the globstar option:

shopt -s globstar

And then run:

rm **/!(mongodb).log

For example:

$ tree
.
├── bar
│   └── baz
│       └── bad
│           ├── file1
│           ├── file2
│           ├── file3.log
│           ├── file4.log
│           ├── file5.log
│           └── mongodb.log
├── file1
├── file2
├── file3.log
├── file4.log
├── file5.log
└── mongodb.log

$ rm **/!(mongodb).log

$ tree
.
├── bar
│   └── baz
│       └── bad
│           ├── file1
│           ├── file2
│           └── mongodb.log
├── file1
├── file2
└── mongodb.log

3 directories, 6 files

From man bash:

If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a |. Composite patterns may be formed using one or more of the fol‐ lowing sub-patterns:

      ?(pattern-list)
             Matches zero or one occurrence of the given patterns
      *(pattern-list)
             Matches zero or more occurrences of the given patterns
      +(pattern-list)
             Matches one or more occurrences of the given patterns
      @(pattern-list)
             Matches one of the given patterns
      !(pattern-list)
             Matches anything except one of the given patterns

 

globstar

If set, the pattern ** used in a pathname expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a /, only directories and subdirectories match.