Question: I can't figure out how the find -not works.

Let's say that I would like to locate all .git dirs in the tree.

```
find -type d -iname .git

```

No problems, but then let's say that I have some dirs that I don't like to be included, in question they can be called "old" and "backup".

I could pipe to grep -v and that will work just fine.

```
find -type d -iname .git | grep -v old | grep -v backup

```

But when I browsed the man page for find I noticed that there is a -not, but I can't figure out how it is intended to work.

I tried like this, but he does not exclude the old dir.

```
find -type d -iname .git -not -iname old 

```

How does the find -not work? Can I use it for this find of problem?

Answer: 
You could exclude the directories by specifying `-path`:

```
find . -type d \( -iname .git ! -path "*/old/*" ! -path "*/backup/*" \)

```

Note that `-not` in GNU `find` is the same as `!` but is not POSIX compliant.

Quoting from `man find`:

```
   ! expr True  if  expr  is false.  This character will also usually need
          protection from interpretation by the shell.

   -not expr
          Same as ! expr, but not POSIX compliant.

```
> 
> 
> ```
> find -type d -iname .git -not -iname old 
> 
> ```
> 
> 

This matches directories which are called `.git` and not called `old`. Since a directory which is called `.git` cannot be called `old`, the `-not -iname old` part can be removed without changing the meaning of the command.

`-not` says “don't match”, but not “don't recurse into”. There's a different way to say “don't recurse into”: it's an action called `-prune`. The following command means “traverse all directories recursively (`find`), but stop at directories called `old` (`-iname old -prune`), and print directories called `.git`”:

```
find -iname old -prune -o -type d -iname .git -print

```

This is parsed as `( -iname old -prune ) -o ( -type d -iname .git -print )`. Find is told to look for files that meet the conditions `-iname old` or (`-o`) `-type d -iname .git`. When a file meets the first condition, the action `-prune` (prune from the traversed tree, i.e. don't recurse) is executed. When a file meets the second condition, the action `-print` is executed. As printing is the default action, you can omit `-print`.