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.
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.
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.