How can I use the find
command to locate directories that do NOT contain a particular file? E.g., if I have bunch of directories that should be under revision control, can I search and find the ones that do not have a .git
sub-directory? Or, my project specifies that all modules should have a utilities.py
file; how do I search to find which sub-directories do not yet have the required file?
1 Answer
The solution that might work for your case is,
find . -type d '!' -exec test -e "{}/utilities.py" ';' -print
Testing
- I created 4 sub directories named dir1, dir2, dir3 and dir with spaces. I wanted to test if this handles spaces equally well which is why I created a directory with spaces in its name.
- I created files file1, file2, file3 and file4 in dir2 and dir3.
- In dir1, I created file1, file2, file3.
- In dir with spaces, I created a file named file with spaces.
Now, I execute my find command as,
find . -type d '!' -exec test -e "{}/file with spaces" ';' -print
The output I get is,
. ./dir1 ./dir2 ./dir3
As expected, since the directory dir with spaces contains the file named file with spaces it is not listed in the output. If I change the
find
command to have file4 in it, the output I get is,. ./dir with spaces ./dir1
EDIT
However, the above approach doesn't seem to work if we have nested subdirectories and the file in the final level. So to overcome such scenarios, you could modify your find to something like discussed over here.
find . -type f -not -name 'utilities.py' -exec dirname {} \; | sort -u
As Gilles suggests in his comments,
For
.git
, it would be more useful to skip directories that have a parent containing.git
. You can do this by adding a -prune in the right place:find . -type d -exec test -e "{}/.git" ';' -prune -o -print
-
This will list all files and directories except utilities.py, without telling me which DIRECTORIES do NOT have that file in them.– ChrisDRCommented Sep 29, 2014 at 15:19
-
1
-
+1 but I'd delete the first suggestion since it does not help the OP.– terdon ♦Commented Sep 29, 2014 at 15:53
-
@terdon, thanks. I deleted it. But it seems the latest edit is something what the OP might be interested in since it deals with the subdirectories as well.– RameshCommented Sep 29, 2014 at 15:55
-
3For
.git
, it would be more useful to skip directories that have a parent containing.git
. You can do this by adding a-prune
in the right place:find . -type d -exec test -e "{}/.git" ';' -prune -o -print
Commented Sep 29, 2014 at 23:00