Find exclude specific folders/directories

Hi ,

I would like to exclude certain folder/directory paths from my search criteria. But it seems to not work. Here is what I have so far:

set find_dir to quoted form of ("/A1/")
set file_name to quoted form of "*"
set theExcludePosPath to quoted form of "/A1/Test/"
set theExcludePosPath2 to quoted form of "/A1/Test2/"

do shell script "find " & find_dir & " -type f -name  " & file_name & " ! -path " & theExcludePosPath & " ! -path " & theExcludePosPath2 & "  "

I am still getting the files listed in the test folders. It’s as if the -path instruction doesn’t stick. I think my syntax might be wrong.

Please help !!

Thx !

All the find clauses are joined together by an implicit “-a” (logical and). What you have there translates as this:

if (it is a file) [-type f] and (its name matches *) [-name *] and (its path does not match "/A1/Test/") [! -path .] and (its path does not match "/A1/Test2/") [! -path .] then (print its path) [implicit]
You need to use “-prune” to prevent traversal of a particular directory. Otherwise all you are doing is skipping the “-print” for the directories themselves (which is already accomplished by “-type f”).

You also need to mind those trailing slashes. You must omit them for the paths you want match against. Also, if you do not omit it in find_dir, you will have to use a double slashe after “A1” in the paths to match (“/A1/” implies “/A1//Test” and “/A1//Test2”).

Here is one way to skip entire hierarchies rooted at a couple of directories:

set find_dir to quoted form of ("/A1")
set file_name to quoted form of "*"
set theExcludePosPath to quoted form of "/A1/Test"
set theExcludePosPath2 to quoted form of "/A1/Test2"

do shell script "find " & find_dir & " \\( -path " & theExcludePosPath & " -o -path " & theExcludePosPath2 & " \\) -prune -o -type f -name " & file_name & " -print"

The clauses are structured so that if either of the paths match then deeper traversal is aborted and nothing is printed for the directory itself. Otherwise the check for a plain file and matching name controls whether is is printed (“-print” must be explicit to avoid an implicit “-print” for the pruned directories).

I assume you will change the file name pattern. “*” will always match any filename, which makes checking for it a useless “no op”.

Model: iBook G4 933
AppleScript: 1.10.7
Browser: Safari 4 Public Beta (4528.17)
Operating System: Mac OS X (10.4)

Thank you Chrys !!

I understand parts of your explanation.

Not sure I understand what you mean by:

because I want to get file path references to all files except the ones in the exclude directories.


I don’t understand the meaning for “explicit” and “implicit” and how it relates to “-print”.

Sorry if this is basic stuff but I am learning.

Thanks for the great explanation of my original syntax.


As a filename pattern, * matches any filename. It can never filter out any files for processing one way or another (e.g. printing or not printing). If you just want to print the paths to all the files, use " -type f -print ". Adding " -name ‘*’ " in there will never cause any more nor any less pathnames to be printed.

An implicit “-print” is one that the find command automatically adds if the user did not include one (implicit ~ implied ~ not actually present, but understood to be present). Including a “-print” or “-print0” argument disables the implicit (automatic) “-print” behavior (explicit ~ plainly visible).

Maybe a bit of history will help to clarify. In older versions of find if you did not include a “-print” command, find would go about its business searching as you specified with your other arguments (“-name ‘*.txt’”, etc.) but it would never print anything out. It would read all the directories and subdirectories but it would never print anything because the user never included a “-print” command. Later versions of find (like the ones in recent versions of Mac OS X) adopted a change in behavior that automatically included a “-print” command if no output/action arguments were given on the command line (from the manpage: “If none of -exec, -ls, -print0, or -ok is specified, the given expression shall be effectively replaced by ( given expression ) -print”).