find with prune option help needed

Hello, I am using ksh93 (/usr/dt/bin/dtksh) on Solaris and am stuck when trying to use find with the -prune option.

I need to search a directory (supplied in a variable) for files matching a certain pattern, but ignore any sub-directories.

I have tried:

find ${full_path_to_dir_to_search} -type f -name "*.dat" -print -o -type d -prune

which produces no output. If I cd to that directory and issue this command:

find * -type f -name "*.dat" -print -o -type d -prune

it works as expected since it is working on a list of filenames.

Why doesn't it work when using a full path? I suspect it is being omitted by the -type d -prune option since I am using a full path? If so, how else to do it?

Oh and the sub-directories could change so I can't exclude them specifically in the find command.

Thanks for your consideration,
Gary

Hi gary_w,

As I understand, the option you are looking for is:

-maxdepth 1

which doesn't descend into directories.

Substitute '-prune' with '-maxdepth 1', and an absolute path doesn't mind.

Regards,
Birei

This version of find does not appear to have the maxdepth option. I will study the man page for an alternative hopefully.

Using "-prune" is essentialy the same as using "-maxdepth 1"

I'm assuming "full_path_to_dir_to_search" already contains a splat in order to create the list?

find ${full_path_to_dir_to_search}/* -type f -name "*.dat" -print -o -type d -prune

No it is a full pathname. Note that using a period while in the directory does not work either (no output):

find . -type f -name "*.dat" -print -o -type d -prune

where this does work (my test file is found):

find * -type f -name "*.dat" -print -o -type d -prune

I assume because the period is a directory and the splat is a list of files?

I think the problem is that you're using -prune with a full path which behaves as if you were using a dot.

So it means it will go 0 levels down looking for the files. If you want the command to go down just one level you have to explicitly "add one more level" by appending "/*" to the path.

.       = go down 0 levels
./*     = go down 1 level
./*/*   = go down 2 levels
etc...

One way of achieving the effect of "-maxdepth 1" is to work from the directory above the one you are actually interrogating. Then apply the "-prune" to stop find searching deeper.

#!/bin/ksh
DIR="${1}"
if [ "${DIR}""X" = "X" ]
then
        DIR="`pwd`"
fi
if [ ! -d "${DIR}" ]
then
        echo "${PN}: Directory missing: ${DIR}"
        exit
fi
########################
# Processing starts here
########################
echo "Directory: ${DIR}"
DIRA=`basename "${DIR}"`        # Directory name
cd "${DIR}"
echo "DIRA=${DIRA}"
find ../"${DIRA}" \( ! -name "${DIRA}" -prune \) -type f -print | sort | \
while read FILENAME
do
        FILENAME2=`basename "${FILENAME}"`
        echo "${FILENAME2}"
done

Actually my "${full_path_to_dir_to_search}" variable could contain multiple directories to search, separated by spaces. It was working fine when those directories did not have any sub-directories. Now a new directory being added to the search list has sub-directories thus causing my problem.

I think I am going to have to rethink my approach to handling this condition and loop through each dir_to_search separately. I was hoping to do it in one command.

At any rate, I appreciate your help!

Gary

Imho. There is no harm in looping through the directories individually, it is the only way which will work without complex code.
Don't hold a list in an Environment Variable. It will go wrong if any filename or directory name contains space characters.

Here's what I ended up doing which seems to work although I have more testing to do. ${DAT_CHK_DIRS} is the space separated list of paths (We will never have a filename containing a space):

for search_dir in ${DAT_CHK_DIRS}
do
  find ${search_dir}/* -type d -prune -o -type f -name "*.dat"  \
    -exec echo {} >> ${ERRFILE} \; 2>/dev/null
done

Any .dat files found will be concatenated onto the end of the $ERRFILE (as they should not exist). Just seems inefficient to have to loop through each directory instead of find doing it all but oh well.