0

I have many file extension in directory: .tr0, .scs, .mt0, .ic0, .log, .st0, .pa0.

I want to keep just .tr0 and .scs and delete all other extension.

Is there any effective way instead of:

rm *.mt0 *.ic0 *.log *.st0 *.pa0 
cuonglm
  • 153,898

2 Answers2

2

POSIXLY:

find . ! \( -name '*.tr0' -o -name '*.scs' \) -type f -exec echo rm -f {} +

(Remove echo when you want to execute command)

If your find support -delete:

find . ! \( -name '*.tr0' -o -name '*.scs' \) -type f -delete

The above command will work recursively. If you want in current directory only:

find . ! -name . -prune ! \( -name '*.tr0' -o -name '*.scs' \) -type f
cuonglm
  • 153,898
2

In a shell that allows for extended globbing patterns, such as bash with the extglob shell option enabled (shopt -s extglob) or ksh93:

rm ./*.!(tr0|scs)

The extended shell globbing pattern !(pattern-list) matches anything except the patterns specified in the |-delimited pattern-list.


Note that the pattern also matches directory names if they contain dots, but since rm does not by default remove directories, this would only result in a few error messages.

To work around this, one would use a loop, testing each matching name to make sure it refers to a regular file:

for name in ./*.!(tr0|scs); do
    [ -f "$name" ] && rm "$name"
done
Kusalananda
  • 333,661
  • Here you go, I went through the link you provided, it has good explanation about the problem with ls . use globs instead of ls – Arushix May 24 '18 at 05:29