27

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?

0

1 Answer 1

31

The solution that might work for your case is,

find . -type d '!' -exec test -e "{}/utilities.py" ';' -print

Testing

  1. 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.
  2. I created files file1, file2, file3 and file4 in dir2 and dir3.
  3. In dir1, I created file1, file2, file3.
  4. In dir with spaces, I created a file named file with spaces.
  5. Now, I execute my find command as,

    find . -type d '!' -exec test -e "{}/file with spaces" ';' -print
    
  6. The output I get is,

    .
    ./dir1
    ./dir2
    ./dir3
    
  7. 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
7
  • This will list all files and directories except utilities.py, without telling me which DIRECTORIES do NOT have that file in them.
    – ChrisDR
    Commented Sep 29, 2014 at 15:19
  • 1
    @ChrisDR, please see the updates.
    – Ramesh
    Commented Sep 29, 2014 at 15:27
  • +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.
    – Ramesh
    Commented Sep 29, 2014 at 15:55
  • 3
    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 Commented Sep 29, 2014 at 23:00

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .