Given the following directories structure:

$ tree --noreport dir

├── fileA
├── .hiddenfileA
├── .hiddendirA
|   ├── .hiddenfileB
│   ├── fileC
│   └── fileD
└── dirA
    ├── .hiddenfileC
    ├── fileE
    └── fileF

The requirement is to make a call to find so that files from hidden directories but not hidden files (under not hidden directories) are excluded from the result.

The expected return should be something similar to:


Did some research and found here information that led me to create the following call to find

$ find . -type f -not -path '*/\.*' -print

But this solution has the drawback that skips hidden directories and files.

  • Should a file at the path some/.dir/here/file be returned or not?
    – Kusalananda
    Commented Dec 30, 2019 at 7:48
  • @Kusalananda Since it is under a hidden directory it should not be returned. Commented Dec 30, 2019 at 15:47

2 Answers 2


Prune hidden directories and limit the results to files:

find . -type d -name '.?*' -prune -o -type f -print

As suggested by jthill, you might prefer filtering out directories, which would result in showing files, links etc.:

find . -type d -name '.?*' -prune -o ! -type d -print
  • OCD squishification: find -type d -name '.?*' -prune -o -type f -- but you probably want to end with ! -type d instead of -type f so you get symbolic links and other less-usual types
    – jthill
    Commented Nov 27, 2019 at 16:04
  • Thanks for the simplification! I was following the filter from the question. Commented Nov 27, 2019 at 16:28

The command you have is very close to working.  Use

find . -type f ! -path '*/.*/*' -print
  • The path pattern, */.*/*, looks for a /. (implying a segment name that begins with .) followed (eventually) by a / — so the segment name that begins with . cannot be the last one (the file name); i.e., it must be a directory name.
  • -path uses filename expansion patterns; a.k.a. globs or wildcards.  So you don’t need to put \ before ..
  • Don’t use -not if you want portability to non-GNU systems.  The use of ! to represent “not” is specified by POSIX, and works in every version of find (even BSD, Solaris, etc., and ancient systems).

You must log in to answer this question.

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