You can't use find to look for files that do not exist. However, you may use find to look for directories, and then test whether the given filenames exists in those directories.
When using find to look for directories, make sure that you use -type d. Then test each of the found directories for the files README and readme.
Assuming the following directory hierarchy for some top-directory projects:
projects/
|-- toola
| |-- doc
| |-- readme
| `-- src
|-- toolb
| |-- doc
| `-- src
|-- toolc
| |-- README
| |-- doc
| `-- src
`-- toold
|-- doc
`-- src
Using find to find the directories directly under projects that does not contain a README or readme file:
$ find projects -mindepth 1 -maxdepth 1 -type d \
! -exec test -f {}/README ';' \
! -exec test -f {}/readme ';' -print
projects/toolb
projects/toold
Here, we find any directory directly under projects and then use the test utility to determine which one of the found directories do not contain either of the two files.
This is exactly equivalent of
find projects -mindepth 1 -maxdepth 1 -type d \
-exec [ ! -f {}/README ] ';' \
-exec [ ! -f {}/readme ] ';' -print
Another formulation of the above:
find projects -mindepth 1 -maxdepth 1 -type d -exec sh -c '
for pathname do
if [ ! -f "$pathname/README" ] &&
[ ! -f "$pathname/readme" ]; then
printf "%s\n" "$pathname"
fi
done' sh {} +
Here, we let a small in-line shell script do the actual testing for the two files and print the pathname of the directories that does not contain either of them. The find utility acts like a "pathname generator" of pathnames to directories for the in-line script to iterate over.
In fact, if the directory structure is like this, we may choose to not use find at all:
for pathname in projects/*/; do
if [ ! -f "$pathname/README" ] &&
[ ! -f "$pathname/readme" ]; then
printf '%s\n' "$pathname"
fi
done
Note the trailing slash in the projects/*/ pattern. It's this that makes the pattern only match directories (or symbolic links to directories).
A difference between doing it this way and using find is that with the above shell loop, we will exclude hidden directories under project and will include symbolic links to directories.
In all cases, we iterate over the pathnames of directories, and we test for the non-existence of the two filenames.
The only caveat is that the -f test will also be true for a symbolic link to a regular file.
Related:
-execfor its intended use and not as a weakerxargs.. – pipe Oct 24 '18 at 12:51xargshas its uses, but we don't often need it. – Kusalananda Oct 24 '18 at 12:53