Simple question, I'm running the following find command:

find . -type d \( -path ./.git -o   \
                  -path ./log -o    \
                  -path ./public -o \
                  -path ./tmp       \) \
                  -prune -o         \

To list all the files in my directory, excluding the specified directories.

This works great, however, what I want to also do is exclude any actual directories from the output, so if there is a directory structure as follows:

  -- foo.text
  -- bar.text

when I run my command I'd like to see:


instead of:


Can anybody help?

  • Title does not match content. – ctrl-alt-delor Apr 6 '19 at 21:57
find . -type f

will do it. You can do exec if you want to operate on file names.

  • yes, but I need to exclude all files under certain directories. – TheDelChop May 23 '13 at 19:40
  • -type f is for regular files. directories and regular files are 2 of many different types of files on Unix. With -type f, you're excluding directories, but also all the other types of files like symlinks, sockets, fifos, devices, doors... – Stéphane Chazelas May 23 '13 at 20:07
  • @StéphaneChazelas, doors? – user1717828 Feb 19 '16 at 19:43
  • @user1717828, en.wikipedia.org/wiki/Doors_%28computing%29 – Stéphane Chazelas Feb 19 '16 at 20:12

Just use ! -type d:

find . -type d \( -path ./.git -o \
                  -path ./log -o \
                  -path ./public -o \
                  -path ./tmp \) -prune -o \
       ! -type d -print

Here's one way to do it. I'm piping your output from find (using xargs) to a little bit of bash which asks the question "Is this not a directory?" and if it's not, it echoes it to your terminal.

Here's the whole she-bang:

find . -type d \( -path ./.git -o -path ./log -o -path ./public -o -path ./tmp \) -prune -o -print | xargs -i bash -c 'if [ ! -d "{}" ]; then echo "{}"; fi'

Here's just my addition:

xargs -i bash -c 'if [ ! -d "{}" ]; then echo "{}"; fi'

To explain:

xargs -i replace string "{}" with arguments (those that are piped in)

bash -c commands read from string

if [ ! -d "{}"]; is this a directory.

echo "{}" echo the find result.

fi; finish if.

  • There, you're turning the filename into shell code. Typical privilege escalation path. As one can create a file called $(do-what-I-want) for instance to have you do what he wants. – Stéphane Chazelas May 23 '13 at 20:12
  • This is a cool workaround when one not knowing how to use -o ! -type d. Cool trick! – azbarcea Aug 13 '20 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.