7

I want to write a cleanup routine for my make file that removes every thing except the necessary source files in my folder. For example, my folder contains files with the following extensions: .f .f90 .F90 .F03 .o .h .out .dat .txt .hdf .gif.

I know I can accomplish this with:

find . -name \( '*.o' '*.out' '*.dat' '*.txt' '*.hdf' '*.gif' \) -delete

Using negation, I can do this:

find . -not -name '*.f*' -not -name '*.F*' -not -name '*.h' -delete

But, when I try to do this:

find . -not -name \( '*.f*' '*.F*' '*.h' \)

I get an error:

find: paths must exceed expression: [first expression in the above list]

(In this case, I would get: find: paths must exceed expression: *.f* )

Can you explain why this happens, and how to do what I am trying to do? I just hate writing -not -name every time I want to add a file extension to the list. Also, I want to find out why this is giving me an error so that I can learn Linux better.

Thanks!

ephemient
  • 198,619
  • 38
  • 280
  • 391
Tal
  • 115
  • 2
  • 6
  • The first command `find . -name \( '*.o' '*.out' '*.dat' '*.txt' '*.hdf' '*.gif' \) -delete` should not be working, what makes you think it does? – ephemient May 17 '17 at 16:27
  • Are there subdirectories you need to search as well? Or is everything you want to clean kept in one directory? – MadScientist May 17 '17 at 19:30

1 Answers1

13
find . -not -name \( '*.f' '*.F' '*.h' \)

is interpreted as

find
    .                      # path to search
    -not                   # negate next expression
    -name \(               # expression for files named "("
    '*.f' '*.F' .'*.h' \)  # more paths to search?

leading to the error.

Since these are single-letter extensions, you can collapse them to a single glob:

find . -not -name '*.[fFh]'

but if they are longer, you have to write out the globs

find . -not -name '*.f' -not -name '*.F' -not -name '*.h'

or

find . -not \( -name '*.f' -o -name '*.F' -o -name '*.h' \)

or switch to using regular expressions.

find . -not -regex '.*\.(f|F|h)$'

Note that regular expressions in find is not part of the POSIX standard and might not be available in all implementations.

ephemient
  • 198,619
  • 38
  • 280
  • 391