Delete All .log files execept for one

I want to delete all files with .log extension on except for one. Is it possible to do that delete all .log files from all folders except for mongodb log files?


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.