1827603 Members
3410 Online
109966 Solutions
New Discussion

While loop

 
SOLVED
Go to solution
Vanquish
Occasional Advisor

While loop

To give a short description what i am doing in the script is reading from a regular text file for the directory structure and changing it to another format and creating the structure, but the problem is once it reads a line from the text file it fails on the second line, I am stuck with the while loop any suggestions please.
Thanks

The REQFILE has
/RIP/module/resources/com/res/app/email/htmlConfirmationEmailHP.txt
RIP/module/resources/com/crm/client/UserMessages.properties
RIP/module/config/html/BrandDetectorServlet.properties


Script:
#!/bin/ksh
STAGEDIR=/home/user/Patch/build_patch/lists
SCRIPTDIR=/home/user/Patch

REQFILE=rip_files.txt
START=(What should I put)
END=`cat $REQFILE|wc -l`
echo $END
while [ $START -lt $END ]
do
for FLPATHNM in `cat $REQFILE`
do
cd $STAGEDIR

FSTCHR=`echo $FLPATHNM|awk '{print substr($0,1,1)}'`
LSTCHR=`echo $FLPATHNM|awk '{print substr($0,length($0),1)}'`
if [ $FSTCHR = "/" ]
then FLPATHNM1=`echo $FLPATHNM|awk '{print substr($0,2,length($0))}'`
else FLPATHNM1=`echo $FLPATHNM`
fi
if [ $LSTCHR = "/" ]
then TFLPATHNM2=`echo $FLPATHNM1|awk '{print substr($0,1,length($0)-1)}'`
else TFLPATHNM2=`echo $FLPATHNM1`

fi
TFLPATHNM4=`echo $TFLPATHNM2|sed 's/RIP\/module\/resources/temp\/RIP\/lib\/resourcepatches/'`
TFLPATHNM4=`echo $TFLPATHNM2|sed 's/RIP\/module\/config/temp\/RIP\/lib\/configpatches/'`

FLPATHNM2=$TFLPATHNM4
LENPATH=`echo $FLPATHNM2|awk '{print length()}'`
SLSHFLG=0
SLSHPOS=X
while [ $SLSHFLG -ne 1 ] && [ $LENPATH -gt 0 ]
do
CHRLKCMP=`echo $FLPATHNM2|awk '{print substr($0,'$LENPATH',1)}'`
if [ $CHRLKCMP = "/" ]
then SLSHFLG=1
SLSHPOS=$LENPATH
fi
((LENPATH = LENPATH - 1))
done
((SLSHPOS = SLSHPOS + 1))
CDPATH=`echo $FILENM|awk '{print substr($0,1,'$LENPATH')}'`
FILENM=`echo $FILENM|awk '{print substr($0,'$SLSHPOS',length())}'`
FSTCHR=`echo $FLPATHNM2|awk '{print substr($0,1,1)}'`
if [ $FSTCHR = "/" ]
then FILENM=`echo $FLPATHNM2|awk '{print substr($0,2)}'`
else FILENM=$FLPATHNM2
fi
LENPATH=`echo $FILENM|awk '{print length()}'`
SLSHFLG=0
SLSHPOS=X
while [ $SLSHFLG -ne 1 ] && [ $LENPATH -gt 0 ]
do
CHRLKCMP=`echo $FILENM|awk '{print substr($0,'$LENPATH',1)}'`
if [ $CHRLKCMP = "/" ]
then SLSHFLG=1
SLSHPOS=$LENPATH
fi
((LENPATH = LENPATH - 1))
done
if [ $SLSHPOS = X ]
then echo "ERROR: "$FILENM": Path Specified Is Incorrect!"
continue
fi
((SLSHPOS = SLSHPOS + 1))
cd /home/user/Patch
CDPATH=`echo $FILENM|awk '{print substr($0,1,'$LENPATH')}'`
echo $CDPATH
FILENM=`echo $FILENM|awk '{print substr($0,'$SLSHPOS',length())}'`
if [ -a $SCRIPTDIR/$CDPATH ]
then cd $SCRIPTDIR/$CDPATH
cp $MODULEDIR/$TFLPATHNM2 $SCRIPTDIR/$CDPATH
else mkdir -p $CDPATH
cp $MODULEDIR/$TFLPATHNM2 $SCRIPTDIR/$CDPATH
continue
fi
echo "-> File: "$FILENM
done
done(end while loop)




1 REPLY 1
Stuart Browne
Honored Contributor
Solution

Re: While loop

Ok, so let me get this straight.

You've got a 'REQFILE' (rip_files.txt) with multiple lines in it, each with a file or directory name listed.

You then want to create a structure somwehere which has all of these files and directories..

You're over-complicating matters here, searching for /'s, instead of using shell commands (basename, dirname) to get this sort of info.

You're also shelling off to awk whenever you want to do any text manipulation commands instead of using shell builtins (${VAR#..}, ${VAR%..}, ${#VAR}).

Your core while loop currently doesn't break out *ever* (as you never increase or decrease either 'START' or 'END').

Lets see if we can shorten this..

#!/bin/ksh
STAGEDIR=/home/user/Patch/build_patch/lists

SCRIPTDIR=/home/user/Patch
MODULEDIR=/some/path

REQFILE=rip_files.txt

while read FILE_PATH
do
FILE_PATH=$(echo ${FILE_PATH}|sed 's#RIP/module/resources#temp/RIP/lib/resourcepatches#')
FILE_PATH=$(echo ${FILE_PATH}|sed 's#RIP/module/config#temp/RIP/lib/configpatches#')

CDPATH=$(dirname ${FILE_PATH})
FILENM=$(basename ${FILE_PATH})

if [ ! -a ${SCRIPTDIR}/${CDPATH} ]
then
mkdir -p ${SCRIPTPATH}/${CDPATH}
fi
cp ${MODULEDIR}/${FILE_PATH} ${SCRIPTDIR}/${CDPATH}
done < ${REQFILE}

Discussion:

Shells's are very robust. Doing things like:

cp /file//to/path/name /another/path//with/slahes

works just fine. The shell understands that it's users are idiots and treats the //'s as a single /.

That being said, the simple in-built:

${CDPATH#/}

would remove any leading slash from the directory names.

The while loop taking input from the file (the 'done < ${REQFILE}') is a valid way to read a list of lines from a file.

The work of finding out the directory-name and file-name can be left to the shell utilities 'dirname' and 'basename' respectivly.

The sed commands. Translating the path mid-stream is nice. 'sed' is a wonderful tool that allows you to replace the separator with a more natural character. As seen above, the normal '/' character has been replaced with a '#' for the separator. This makes it much easier to read and understand, causing less confusion when you come back to it.

As you're going to be doing the copy regardless of whether the path exists or not, there's no point having the copy twice. We do a negative-test for the path accessability, and create it if it's not. You could do a check if the path failed to create at this point if you wanted by changing the 'mkdir -p' line to this:

if ! mkdir -p ${SCRIPTPATH}/${CDPATH}
then
echo "Failed to create path for ${FILE_PATH}"
continue
fi

Thus jumping out of this iteration of the loop.

As you can do copies from one path to another, there's no need to change the directory at any point. After defining 'MODULEDIR' and 'SCRIPTDIR', everything is ready to work regardless of your current-working-directory (or $PWD).

One long-haired git at your service...