0

I'm trying to find all files whose name matches certain C++ file extensions but exclude certain directories matching a pattern with this:

find /home/palchan/code -name "*.[CcHh]" -o -name "*.cpp" -o -name "*.hpp" -a ! -name "*pattern*"

and this still gives me as output certain files like:

/home/palchan/code/libFox/pattern/hdr/fox/RedFox.H

which has the pattern in it?

Here is an example:

> ls -R .
.:
libFox

./libFox:
RedFox.C  RedFox.H  pattern

./libFox/pattern:
RedFox.C  RedFox.H

and then I run:

> find . \( -name "*.[HC]" -a ! -name "*pattern*" \)
./libFox/pattern/RedFox.C
./libFox/pattern/RedFox.H
./libFox/RedFox.C
./libFox/RedFox.H
Palace Chan
  • 8,845
  • 11
  • 41
  • 93

2 Answers2

1

The following should work:

find /home/palchan/code \( -name "*pattern*" \) -prune -o -type f \( -name "*.[CcHh]" -o -name "*.cpp" -o -name "*.hpp" \) -print

From man find:

 -name pattern
          Base of file name (the path with the leading directories removed) matches shell pattern pattern.  The metacharacters (`*', `?', and `[]')  match
          a  `.'  at the start of the base name (this is a change in findutils-4.2.2; see section STANDARDS CONFORMANCE below).  To ignore a directory and
          the files under it, use -prune; see an example in the description of -path.  Braces are not recognised as being special, despite the  fact  that
          some  shells  including  Bash  imbue  braces  with  a special meaning in shell patterns.  The filename matching is performed with the use of the
          fnmatch(3) library function.   Don't forget to enclose the pattern in quotes in order to protect it from expansion by the shell.

So, basically, you should use -prune to exclude directories instead of ! -name something

Community
  • 1
  • 1
higuaro
  • 15,730
  • 4
  • 36
  • 43
0

Try doing this :

find /home/palchan/code \( -name "*.[CcHh]" -o -name "*.cpp" -o -name "*.hpp" -a ! -name "*pattern*" \)
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223