Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm attempting to clean out a bunch of temporary files from a folder tree, but don't want to delete files that match some criteria, specifically executable files, .tpl files, and not the subfolder 'data'.

I see the question here

Delete files in a directory that match a regexp, using a Mac terminal

is almost what I'm looking for, but they have a regex they are trying to match, and I have a regex that I don't want matches. I can do this to find all of the files I don't to delete:

find . -executable -o -regex '.*\.tpl'

Is there a way to invert the matches, like -v does with regex?

share|improve this question
add comment

2 Answers 2

up vote 6 down vote accepted

Is there a way to invert the matches, like -v does with regex?

Use negation(!):

find . -executable -o ! -regex '.*\.tpl' -exec rm -i {} \+
share|improve this answer
    
Ah, I didn't know about the negation! From here I was able to figure out to use -a rather than -o, So the final command looks like find . ! -executable -a ! -regex '.*\.tpl' -exec rm -i {} \+, which matches my criteria of deleting everything except executables, subfolders, and .tpl files. –  EvilAmarant7x Jun 27 '11 at 15:22
add comment

A convenient way to run a command for everything except files matching certain conditions is to exploit -o's short-circuiting behavior, e.g. find -cond1 -cond2 -o -exec command means “if cond1 and cond2 then do nothing, else execute command”.

find . -type f -executable -o -name '*.tpl' -o -exec rm -i {} \+

To exclude the data directory, use the -prune action, which means “skip this directory and don't recurse into it”. Use -name data to match all directories called data, or -path ./data to match only at the toplevel.

find . -type f -executable -o \
       -name '*.tpl' -o \
       -type d -name data -prune -o \
       -exec rm -i {} \+

Bonus: the same in zsh.

rm -i -- **/*~*.tpl~data/*(.^*)
  • The ~ operator excludes files matching certain patterns (you must do setopt extended_glob first).
  • **/ performs recursive globbing
  • The . glob qualifier restricts the whole match to regular files, and ^* excludes executable files (^ negates the qualifiers that come after it; qualifiers are anded).
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.