Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude list of file extensions from find in bash shell

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!

like image 368
Tal Avatar asked May 17 '17 16:05

Tal


People also ask

How do I exclude a specific file in Linux?

Exclude Files and Directories from a List. When you need to exclude a large number of different files and directories, you can use the rsync --exclude-from flag. To do so, create a text file with the name of the files and directories you want to exclude. Then, pass the name of the file to the --exlude-from option.

How do I remove extensions in Bash?

Remove File Extension Using the basename Command in Bash If you know the name of the extension, then you can use the basename command to remove the extension from the filename. The first command-Line argument of the basename command is the variable's name, and the extension name is the second argument.

How do you exclude from find?

We can exclude directories by using the help of “path“, “prune“, “o” and “print” switches with find command. The directory “bit” will be excluded from the find search!

How do I get a list of all file extensions?

If you add the -X option, ls will sort files by name within each extension category. For example, it will list files without extensions first (in alphanumeric order) followed by files with extensions like . 1, . bz2, .


1 Answers

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.

like image 152
ephemient Avatar answered Sep 20 '22 08:09

ephemient