Sign up ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free.

I am trying to use shell to find all sub-directories in any directory. What I would want is to have a .sh file (shell script file) that can receive as a parameter the name of the directory I'm interested in and the list of files I want to find (NOTE: I want only sub-directories that have all these files).

I know I can use this:

find $D -perm -u=rx -type f

Where D is the directory, -u is the user, r is the users right to read and x is the right to modify I believe, but uhm I have no idea how to make the file accept parameters and I have no idea how to use -u=rx

EDIT: I now understand how to use parameters for a shell script file, so that's ok. I still don't get most of the rest.

I would love it if someone could either explain the code I mentioned or ... give an alternative ?

I'm also ok with a partial answer, I just need some help.

share|improve this question
this will help you – Web-E May 9 '12 at 12:09
Oh, thank you. I would have googled myself but I had no idea how it was called, my english is good, but not that good. – Kalec May 9 '12 at 12:17

2 Answers 2

up vote 1 down vote accepted

I would interpret your requirements as "find all subdirectories which contain all the specific files"

find "$parent_dir" -type d |
while IFS= read -r subdir; do
  for file in "$@"; do
    if [[ ! -f "$subdir/$file" ]]; then
  $all_present && echo "$subdir"

the "IFS=" and "read -r" parts ensure the value of "dir" contains the actual directory name even if it includes spaces or special characters.

share|improve this answer

If I understand correctly what you want to do, this is the solution:


USAGE="Usage: $0 dir file1 file2 ... fileN\nto find all subdirectories of dir that contain all the given files.\n"

if [ "$#" == "0" ]; then
    printf "$USAGE"
    exit 1


while (( "$#" )); do
  ARG="$ARG -exec test -e \"{}/$1\" \; "

cmd="find $DIR -type d $ARG -print"
eval $cmd

What it does is this:

The use find ... -type d to find all subdirectories (including the directory given as first parameter). The test -e command checks if a file exists. So for a given directory we have to check all the files given in the command line: test -e /path/to/directory/file1 test -e /path/to/directory/file2 test -e /path/to/directory/file3 ... The /path/to/directory is {} - a single result of find. Then the find-parameter -exec can be used to check for a single file. To check for all files several -exec test parameters are needed. So while loop build a list of there parameters, then this list is put together in a single command and evaluated.

Have fun ...

share|improve this answer
Thank you. I'm having problems testing it since this is on a virtual machine and I don't seem to know how to find the name of directories. However I will figure this out, thank you! – Kalec May 9 '12 at 13:59
Take a look at if you have problems using the example. – Thomas May 9 '12 at 14:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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