Find the latest directory and loop through the files and pick the error messages

Hi,

I am new to unix and shell scripting,can anybody help me in sctipting a requirement.

my requirement is to get the latest directory the name of the directory will be like CSB.monthdate_time stamp
like CSB.Sep29_11:16 and CSB.Oct01_16:21.
i need to pick the latest directory.

in the directory there will be a 5 error files like
THerrFile_1.err
THerrFile_2.err
THerrFile_3.err
THerrFile_4.err
THerrFile_5.err.

I need to go thorugh each one of the file and pick the ORA- error codes and ora message from the file.

Please advice.

Actually these are three distinct problems:

1) Find the latest directory and get its name;
2) cycle through all the files of a directory with a given name.
3) pick the ORA-messages

2) and 3) are rather easy to accomplish as long as there is no subdirectory structure possible (like in your requirement). You can use the "ls"-command to cycle through all directory entries and pipe the output of it into a while-loop. There you can use "grep" on these files:

#!/bin/ksh

# uncomment the following line to watch the script run:
# set -xv

typeset fFileName=""
typeset fDirectory="/path/to/your/directory"

ls ${fDirectory} | while read fFileName ; do
     # /path/to/yourcommand "${fFileName}" will cycle through the files
     print - "--------------------[ ${fFileName} ]--------------------------"
     grep "^ORA" ${fFileName}
done

Run this little script and try to understand how it works. Concepts to grasp are: (1) pipelines and how they work; (2) variable expansion; (3) the "while...read"-loop in ksh.

Your first problem - finding the latest directory - is a little more tricky, depending on your situation: every directory entry (that includes directories) has a time stamp and you can tell the "ls"-command to sort the entries by that time stamp (instead of alphabetically, which is the default). It might be that you are looking for the directory with the latest time stamp and in this case you can use the output of "ls -t" and snip off the first line - it will contain the youngest directory entry:

#!/bin/ksh

# uncomment the following line to watch the script run:
# set -xv

typeset fFileName=""
typeset fDirectoryBase="/path/to/your"
typeset fDirectory=""

# determine the latest directory in "$fDirectoryBase", then put the found name behind
# of what in "$fDirectoryBase" is, plus a separating "/" :

fDirectory="${fDirectoryBase}/$(ls -t ${fDirectoryBase} | head -1)"

ls ${fDirectory} | while read fFileName ; do
     # /path/to/yourcommand "${fFileName}" will cycle through the files
     print - "--------------------[ ${fFileName} ]--------------------------"
     grep "^ORA" ${fFileName}
done

If the directories you look at have to be sorted by their names and their time stamps do not correspond your task will be a bit more difficult. Write again in this case and i will show you a solution for this.

I hope this helps.

bakunin

Hi,

thanks Bakunin.

The problem is that there is a log file CSB_control.log this comes up as the latest file.
if i am using ls -ltrd CSB*|tail -1

so the latest directory is not comming.

Please help.

You could use a more elaborate filename mask to search for:

ls -t CSB.[A-Z][a-z][a-z][0-9][0-9]_[0-9][0-9]:[0-9][0-9]

Search for "file globs" or "file globbing" to find out how this expression works.

I hope this helps.

bakunin

Hi,

 
#catr.ksh
#!/bin/ksh

v=""
a=ls -ltrd CSB.*|tail -1
cd a
rm oraerr_output.txt
for j in 1 2 3 4 5
do
v="THerrFile_$j.err";
grep -i "$j:Error" $v >>oraerr_output$j.txt
cat oraerr_output$j.txt >> oraerr_output.txt
rm oraerr_output$j.txt
done
 

when i execute the above code it says.

./ora_error.sh[5]: -ltrd:  not found
./ora_error.sh[6]: a:  not found
rm: oraerr_output.txt: No such file or directory
grep: can't open THerrFile_2.err
grep: can't open THerrFile_3.err
grep: can't open THerrFile_4.err
grep: can't open THerrFile_5.err

please advice.

One of the reason for the error: command substitution miss..try..

a=$(ls -ltrd CSB.*|tail -1)
cd $a

The line a=ls -ltrd CSB.*|tail -1 should be

a=`ls -ltrd CSB.*|tail -1`

Then

cd $a

hi Guy's

Thanks for the help.
i changed the code accordingly.
but i am facing the below error message.

>./ora_error.sh
./ora_error.sh[6]: cd: bad argument count
grep: can't open THerrFile_2.err
grep: can't open THerrFile_3.err
grep: can't open THerrFile_4.err
grep: can't open THerrFile_5.err

There are quite a few reasons to those errors..

1.The value of the variable a holds something like

. So when u try to change directory (cd $a) the shell will be unable to do so and throws the above error.Hence try to give the correct directory name to cd
2.Also make sure the argument to cd is given as absolute path (if changing to different directory)

Make sure above such file exist in the current working dir. i.e where you have saved/run this shell script.Else specify the correct path.

Thanks Micheal.

How can we tuncate the information i.e

drwxrwsr-x 2 tia uniqgrp 12288 10 Oct 00:30 CSB.Oct10_00:01/

i need to get only the directory name i.e CSB.Oct10_00:01 part
but not the entire line.

please advice.

---------- Post updated at 09:55 AM ---------- Previous update was at 08:38 AM ----------

Hi,

 
#catr.ksh
#!/bin/ksh

v=""
a='ls -ltrd CSB.*|tail -1|egrep -v '^CSB.*'|awk '{ print$9 }''
cd $a
rm oraerr_output.txt
for j in 1 2 3 4 5
do
v="THerrFile_$j.err";
grep -i "$j:Error" $v >>oraerr_output$j.txt
cat oraerr_output$j.txt >> oraerr_output.txt
rm oraerr_output$j.txt
done
 

in the above code for variable a i am getting a directory name.
but in "Cd $a" it is not going into the directory.

because i am getting the below errors.

}
grep: can't open THerrFile_1.err
grep: can't open THerrFile_2.err
grep: can't open THerrFile_3.err
grep: can't open THerrFile_4.err
grep: can't open THerrFile_5.err

Please advice if the above code is correct or i am going wrong some where.

1.It wud have been better if you have posted the value of a. Looking the above code seems like var a is not executed.Try as below as prev said..

a=$(ls -ltrd CSB.*|tail -1|egrep -v '^CSB.*'|awk '{ print$9 }')

Do not use those single quotes- ' '

  1. Before grep'ing the file THerrFile_*.err take sometime to check if that file exist in your current working dir or where this script is stored.As the error states
  • there is no such file in the current dir.
1 Like

Just omit the "-l" switch from the "ls"-command. Instead of "ls -ltrd ...." use "ls -trd ...."

I hope this helps.

bakunin

Hi,

Thanks Micheal,

For the point-2:

once the cd command is executed then i can grep the files in the directory.As the directory is not changing i am not able to grep and it says can't open the THerrFile_2.err file.

the value of a will be like CSB.Oct11_17:30.

it is not working .

please help.

-------

It is working fine now.
I am copying the final code.hope it may help some one.

#catr.ksh
#!/bin/ksh
 
v=""
a=$(ls -ltrd CSB.*|tail -1|egrep -v '^CSB.*'|awk '{ print$9 }')
cd $a
rm oraerr_output.txt
for j in 1 2 3 4 5
        do
                v="THerrFile_$j.err";
                grep -i "$j:Error" $v >>oraerr_output$j.txt
                cat oraerr_output$j.txt >> oraerr_output.txt
                rm oraerr_output$j.txt
done

Thanks guys for your help.

Hi,

the code that i pasted in my previous posts works fine ,if all files are existing.if any file is missing it is comming out.

but my requirement is,it should go to next file and grep the ora-messages.
i am copying my code also.

for example if we couldn't find THerrFile_1.err file in the directory.it is comming out,it should go to
THerrFile_2.err ,THerrFile_3.err ,THerrFile_4.err ,THerrFile_5.err files and pick the ora-messages.

please advice.

 
#catr.ksh
#!/bin/ksh

v=""
a=$(ls -ltrd CSB.*|tail -1|egrep -v '^CSB.*'|awk '{ print$9 }')
cd $a
rm oraerr_output.txt
for j in 1 2 3 4 5
do
v="THerrFile_$j.err";
grep -i "$j:Error" $v >>oraerr_output$j.txt
cat oraerr_output$j.txt >> oraerr_output.txt
rm oraerr_output$j.txt
done
 

You could redirect the error to some error.txt file by

grep -i "$j:Error" $v >>oraerr_output$j.txt 2>>error.txt

2 is the file descriptor for standard error generated.
Or give a test condition for file-exist before grep'ing

for j in 1 2 3 4 5
do
	v="THerrFile_$j.err"
	if [ -f "$v" ]
	then
		grep -i "$j:Error" $v >>oraerr_output$j.txt
		cat oraerr_output$j.txt >> oraerr_output.txt
		rm oraerr_output$j.txt
	fi
done
1 Like

Hi,

Thanks Micheal.
It is working fine.