find command from a shell script

Hi experts,
I have a shell script (korn shell on aix) where I am giving find command with file options which are read from a configuration file. For some reason I am getting an error find: 0652-017. I have put set -x in the shell script and the command looks okay. If I cut it and paste it in the dollar prompt the command works. I have spent so many hours trying to find out the problem, but no success. Here is the output from the shell

+ find /tmp -type f -a ! \( -name ".Z" -o -name ".gz" -o -name "DUMMY_" -o -name "testfile_160108.gz" \) -a -name "testfile_1" -a -mtime +0 -print
find: 0652-017 ! \( -name ".Z" -o -name ".gz" -o -name "DUMMY_*" -o -name "testfile_160108.gz" \) is not a valid option.

any idea why it works when pasted on the dollar prompt but not from within a shell ?

Many times ESCAPE or \ has bit behaviroal difference when it used on shell-prompt and in shell-script. Following command will work for you

find /tmp -type f -a \! \( -name ".Z" -o -name ".gz" -o -name "DUMMY_" -o -name "testfile_160108.gz" \) -a -name "testfile_1" -a -mtime +0 -print

Thank you very much for your help sumit. Escaping ! didn't work for some reason.

I will post the full code and the test data for better clairity. The purpose of the script is to zip files which are older taking parameters from a configuration file.

Here is the dat in the configuration file.

# * This File contains the data for performing
# * File housekeeping by the job housekeeping.sh.
# *
# * Each entry should have:
# * 1) Job Title
# * 2) Directory to be addressed (all sub-directories WILL be included)
# * 3) File name (* can be used as a wildcard)
# * 4) Mininum Number of files to retain (Deletion only)
# * 5) Age of the files (days) to be addressed
# * 6) Function - (C)ompress or (D)elete
# ************************************************************************
#
#JOB DIRECTORY FILE FILES AGE FUNC Exclude
#
#================================================================================================
#
HB02 /tmp testfile_1* 0 3 C DUMMY_, testfile_1601
~

Here is the full script

#!/bin/ksh
MODE=""
$MODE
set -x

grep -v '^#' test1.dat |
while read JOB DIRECTORY FILE MIN_FILES TIME FUNCTION EXCEPT
do

     EXCEPT_STRING='\\! \\\( -name "*.Z" -o -name "*.gz" -o '
     con_flag=''
     for exceptfile in \`echo $\{EXCEPT\} | tr ',' ' ' \`
     do
             EXCEPT\_STRING="$EXCEPT_STRING $\{con_flag\} -name \\"$\{exceptfile\}\\" "
             con_flag='-o'
     done
     EXCEPT\_STRING=$EXCEPT_STRING'\\\)'
     echo 'Except string : = ' $EXCEPT_STRING
     BEFORE=$\(find $DIRECTORY -type f -a "$EXCEPT_STRING" -a -name \\"$FILE\\" -a -mtime \+$TIME -print |wc -l\)

done

Here is the output I am getting.
+ read JOB DIRECTORY FILE MIN_FILES TIME FUNCTION EXCEPT
+ grep -v ^# test1.dat
+ EXCEPT_STRING=\! \( -name ".Z" -o -name ".gz" -o
+ con_flag=
+ tr ,
+ echo DUMMY_, testfile_160108.gz
+ EXCEPT_STRING=\! \( -name "
.Z" -o -name ".gz" -o -name "DUMMY_"
+ con_flag=-o
+ EXCEPT_STRING=\! \( -name ".Z" -o -name ".gz" -o -name "DUMMY_" -o -name "testfile_160108.gz"
+ con_flag=-o
+ EXCEPT_STRING=\! \( -name "
.Z" -o -name ".gz" -o -name "DUMMY_" -o -name "testfile_160108.gz" \)
+ echo Except string : = \! \( -name ".Z" -o -name ".gz" -o -name "DUMMY_" -o -name "testfile_160108.gz" \)
Except string : = \! \( -name "
.Z" -o -name ".gz" -o -name "DUMMY_" -o -name "testfile_160108.gz" \)
+ + wc -l
+ find /tmp -type f -a \! \( -name ".Z" -o -name ".gz" -o -name "DUMMY_" -o -name "testfile_160108.gz" \) -a -name "testfile_1" -a -mtime +3 -print
find: 0652-017 \! \( -name ".Z" -o -name ".gz" -o -name "DUMMY_*" -o -name "testfile_160108.gz" \) is not a valid option.
BEFORE= 0
+ read JOB DIRECTORY FILE MIN_FILES TIME FUNCTION EXCEPT

Following piece of code works for me. This simply removes double-quote around EXCEPT_STRING in real find command, and remove un-wanted ESCAPE i.e. \ for EXCEPT_STRING creation

#!/bin/ksh
MODE=""
$MODE
set -x

grep -v '^#' test1.dat |
while read JOB DIRECTORY FILE MIN_FILES TIME FUNCTION EXCEPT
do

     EXCEPT_STRING=' ! \( -name "*.Z" -o -name "*.gz" -o '
     con_flag=''
     for exceptfile in \`echo $\{EXCEPT\} | tr ',' ' ' \`
     do
             EXCEPT\_STRING="$EXCEPT_STRING $\{con_flag\} -name \\"$\{exceptfile\}\\" "
             con_flag='-o'
     done
     EXCEPT\_STRING=$EXCEPT_STRING'\)'
     echo 'Except string : = ' $EXCEPT_STRING
     BEFORE=$\(find $DIRECTORY -type f -a $EXCEPT_STRING -a -name \\"$FILE\\" -a -mtime \+$TIME -print |wc -l\)

done

Sumit, thanks a million for your help. I spent so many hours trying to figure out. I can understand removing the backslash, but I am very curious to know how did you figure out the problem was with the double quotes and reason for it ?

Thanks once again

Just an eagerness to help you!!! BTW its just trial and error with those special characters... As I mentioned in my first reply there are usual problems in Shell-Script with brackets (), back-space, ESCAPEs, and now quotes and double-quotes as well!!!
Also you can see what exactly happening with "sh -x shell-script-name.sh" to debug properly

Sumit, sorry to bother you. Eventhough the scripts works without any complaint, the find command really doesn't find the required files. If you get some time please can you have another look. I tried putting \ before the meta characters, but then it gives error while running the scripts.
You may touch or create those files in a directory to test it.

Thanks once again.