Using shell find all sub-directories that contain certain files

6,407

Solution 1

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

#!/bin/bash
parent_dir="$1"
shift
find "$parent_dir" -type d |
while IFS= read -r subdir; do
  all_present=true
  for file in "$@"; do
    if [[ ! -f "$subdir/$file" ]]; then
      all_present=false
      break
    fi
  done
  $all_present && echo "$subdir"
done

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

Solution 2

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

#!/bin/sh

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
fi

ARG=""
DIR=$1
shift

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

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:
6,407

Related videos on Youtube

Kalec
Author by

Kalec

Student and recent employee. Massive n00b.

Updated on September 18, 2022

Comments

  • Kalec
    Kalec over 1 year

    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.

  • Kalec
    Kalec almost 12 years
    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!
  • Thomas
    Thomas almost 12 years
    Take a look at wikihow.com/Write-a-Shell-Script-Using-Bash-Shell-in-Ubuntu if you have problems using the example.