htmlfiles.txt.$ find . -path ./private -prune -o -name '*.html' -print > htmlfiles.txt
The period immediately after the find, i.e., find .
tells find to start its
search from the current directory from which the command is being
executed; I could use something like find /somedir to start
the search in a different directory.
The -path ./private -prune -o tells find that for the directory
path that is ./private - the dot (.) represents the
current directory, so the path is the private directory below
the current directory - don't include it in the search, i.e., "prune" that
directory from the search path. Including
-prune indicates, if the file is a directory, do not descend into it.
But it is the "dash o", i.e., -o which ensures that nothing is
printed from within that directory.
The o is an operator -
see Combining Primaries With Operators which
means "or" and you can use -or as a substitute for it:
expr1 -o expr2
expr1 -or expr2
Or; expr2 is not evaluated if expr1 is true.
So, in this case, by putting it after the -path ./private
-prune, it means if the expression to the left of the -o is
true, i.e, the path matches ./private, then don't even evaluate
the expression to the right of the -o. The expression to the right
of the -o, i.e., -name '*.html' -print indicates if
the name matches *.html, i.e., anything followed by
.html, then print it. So, if the path includes private, the
-print is never acted upon and that directory isn't included.
The other parameters above have the following meaning:
| -name | Find those files that match the specified file names, in
this case any file that has a .html extension on the filename |
| Print, i.e., display the results found |
But what if I want to exclude multiple directories from the results. Then I can use a find statement in the form below:
find . \( -path dir1 -o -path dir2 -o -path dir3 \)
-prune -o print.
E.g., I could use a find statement like the one below:
$ find . \( -path ./private -o -path ./photos -o -path ./ellen/restricted -o -path ./ellen/keepout \) -prune -o -name '*.html' -print > htmlfiles.txt
In the above example, I don't want to include any files in the private
and photos directory immediately below the directory
from which the find command is run. But I don't want to include the
restricted and keepout directories, which are a
couple of subdirectories below the current one, either.
You need to put an
escape
character, i.e., a backslash, "\", before
the opening and closing parenthesis characters. You also need to include a space
after the opening parenthesis character, "(", and before
the closing parenthesis character, ")", otherwise, without
the spaces, I would get the following error message:
$ find . \(-path ./private -o -path ./photos -o -path ./ellen/restricted -o -path ./ellen/keepout\) -prune -o -name '*.html' -print > htmlfiles.txt find: invalid expression; you have used a binary operator '-o' with nothing before it.
If you omit just the first space after the \(, you would get
the error message above. But if you omit just the space before the
\), you would receive the error message "find: invalid
expression; I was expecting to find a ')' somewhere but did not see one."
So be sure to include both spaces.
References: