Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

C shell & nawk 1

Status
Not open for further replies.

piggy213

Programmer
Sep 27, 2002
19
TW
Hi Everybody:
I have a question
This is my program:

#!/bin/csh -f
set month = `date +%b`
set day = `date +%e`
@ yesterday = $day - 1
set yes = $yesterday

if ($yes == 0) then
if ($month == Jan) then
set month = Dec
set yes = 31
endif
if ($month == Feb) then
set month = Jan
set yes = 31
endif
.........................
.........................
if ($month == Mar) then
@ leapyear = `date +%C` %4
set month = Feb
set month = Feb
set yes = 28
if ($leapyear == 0) yes = 29
endif
else
set yestermonth = $month
endif

nawk 'BEGIN { rightday = 0; dateline = "" } $2~~ /'$month'/ && $3 ~~ /'$yes'/ { rightday = 1; dateline = $0 }$2~~ /'$month'/ && $3 ~~ /'$day'/ {exit} rightday == 1 && /ORA/ {print dateline;print}' alert_mes.log


Then I got :

Wed Oct 2 18:25:16 2002
ORA-12012: error on auto execute of job 134
Wed Oct 2 18:25:16 2002
ORA-12541: TNS:no listener
Wed Oct 2 18:25:16 2002
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 794
Wed Oct 2 18:25:16 2002
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 851

But I wanted :
[COLOR=#ffoooo]
Wed Oct 2 18:25:16 2002
Errors in file /raid1/app/oracle/admin/mes/bdump/mes_j000_5985.trc:
ORA-12012: error on auto execute of job 150
ORA-12541: TNS:no listener
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 794
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 851
[/color]
The original file is :
italic
................................................
.................................................
Wed Oct 2 18:25:16 2002
normal xxxxxxxxxxxxxxxxxxxx
Wed Oct 2 18:25:16 2002
Errors in file /raid1/app/oracle/admin/mes/bdump/mes_j000_5985.trc:
ORA-12012: error on auto execute of job 150
ORA-12541: TNS:no listener
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 794
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 851
................................................

That is to say if it meet the "ORA" words I wanted to print all lines which are below the date.
Thank you very much.
piggy
 
Code:
#!/bin/sh
# get todays date ...
set todaymonth = `date +%b`
set todayday = `date +%e`
# get yesterdays date ... the easy wayTZ="$TZ+24"
export TZ
set yesmonth = `date +%b`
set yesday = `date +%e`

nawk 'BEGIN { rightday = 0 } $2~~ /'$yesmonth'/ && $3 ~~ /'$yesday'/ { rightday = 1; print $0 } $2~~ /'$todaymonth'/ && $3 ~~ /'$todayday'/ {exit} rightday == 1 && /ORA/ {print}' alert_mes.log

by the way your previous program had a problem on the first of the month ...
 
hmm ... ok, that should have been (without the 'set's)

Code:
#!/bin/sh
# get todays date ...
todaymonth=`date +%b`
todayday=`date +%e`
# get yesterdays date ... the easy way
TZ="$TZ+24"
export TZ
yesmonth=`date +%b`
yesday=`date +%e`

nawk 'BEGIN { rightday = 0 } $2~~ /'$yesmonth'/ && $3 ~~ /'$yesday'/ { rightday = 1; print $0 } $2~~ /'$todaymonth'/ && $3 ~~ /'$todayday'/ {exit} rightday == 1 && /ORA/ {print}' alert_mes.log
 
DO NOT WRITE csh SCRIPTS !!!!!!!!!!!!!
USE sh OR ksh vox clamantis in deserto.
 
Jad: Check the other thread from Piggy123. The TZ trick is seriously flawed. To see this type (in ksh)
date
TZ="$TZ+24" date

As an example, when I did this just now I got:
$ date
Thu Oct 3 11:41:32 CDT 2002
$ TZ="$TZ+24" date
Wed Oct 2 16:41:49 CDT 2002

As you can see, it got yesterday's date, but not at the same time. If I were to do the same thing at 7:30 this evening, this is what I would get:
$ date
Thu Oct 3 19:30:00 CDT 2002
$ TZ="$TZ+24" date
Thu Oct 3 00:30:17 CDT 2002

So much for it always giving yesterday's date! The TZ trick only works correctly for Coordinated Universal Time (aka Greenwich Mean Time). It can still be done by a more complex modification of TZ, but I did not want try and spring this on a novice. (If the you know the program will always be run in the same timezone, you can do a simple timezone-dependent change to TZ, but say goodbye to portability!)

Piggy123: Sorry not to have replied earlier, but I have to work on my own job sometime. I am a little confused here: the data you are showing now follows a different format than what you were asking about before. Has the style of the log changed? Or are you trying to do something different than before. Do you still want lines with :error in them reported and lines with :normal not reported? All of these lines in your original example, including the :normal lines, started with "ORA". Do you want them all now?

Concerning your program as shown: You need to change all of the lines that say "set month=Jan" or "set month=Feb", or ..., to "set yesmonth=Jan" , "set yesmonth=Feb", ... . Also, delete the "set yestermonth=$month" line, and change the part of your nawk program that says

$2~~ /'$month'/ && $3 ~~ /'$yes'/

to say

$2~~ /'$yesmonth'/ && $3 ~~ /'$yes'/

If you don't make these changes, your program will NOT work correctly on November 1st, or December 1st, or ...
(you might also delete the extra "set month=Feb" line!)

The problem that I am fixing here is that you are trying to use "month" to hold the month for today, and the month for yesterday. When these are different (which they are on the first of every month), you can not use the same variable to hold BOTH values!

One other suggestion: In C shell you can still write nawk scripts on more than one line. You just have to end each line with "\". (Another reason to use a DECENT shell, like Korn!) Your program will be much easier to read if you write it as:
Code:
nawk 'BEGIN { rightday = 0; dateline = "" }   $2~~ /'$yesmonth'/ && $3 ~~ /'$yes'/ { rightday = 1; dateline = $0 }   $2~~ /'$month'/ && $3 ~~ /'$day'/ {exit}   rightday == 1 && /ORA/ {print dateline;print}   ' alert_mes.log

None of this answers your question this time, it just fixes a bunch of other stuff. You need to explain better how your log is set up and what exactly it is you want out of it. Otherwise we will keep up this business of going back and forth whenever your program runs into something it has not been designed to handle.

 
Hi,Daedelus
Yes, I was trying to do something different than before and was requested by user. I'm sorry aboout confusing you last time. This time I will try to explain clearly as soon as possible.

This time I still find out yesterday' messages which is different format than before.

If the alert.log file(original file) is:

Wed Oct 1 08:25:16 2002
.................................................
Wed Oct 3 08:25:16 2002
Thread job in file /raid1/app/oracle/admin/mes/bdump/mes_j000_5985.trc:
Current is nothing
Wed Oct 3 18:25:16 2002
Errors in file /raid1/app/oracle/admin/mes/bdump/mes_j000_5985.trc:
ORA-12012: error on auto execute of job 150
ORA-12541: TNS:no listener
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 794
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 851
Wed Oct 4 12:25:16 2002
....................................................
....................................................

I just want the following data:bold

Wed Oct 3 18:25:16 2002
Errors in file /raid1/app/oracle/admin/mes/bdump/mes_j000_5985.trc:
ORA-12012: error on auto execute of job 150
ORA-12541: TNS:no listener
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 794
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 851

[COLOR=#ffoooo]
What I want is if the yesterday's messages which below date line has "Errors" words print all lines from yesterday date line through the last 'ORA....' line.[/color]
The original file,alert.log, were fixed :
If 'Errors' word messages appeared, the 'Errors.....' line just single one and must below the date line and the other 'ORA....' lines were fixed 4 lines. So last I will print 6 lines.
In fact, I tried to use nawk built-in function "getline" but failed. Do you have any good idea?

Thank you, Daedelus
 
Okay, try this:
Code:
nawk 'BEGIN { rightday = 0; dateline = "" }   $2~~ /'$yesmonth'/ && $3 ~~ /'$yes'/ {rightday = 1; dateline = $0 }   $2~~ /'$month'/ && $3 ~~ /'$day'/ {exit}   rightday == 1 && /^Errors/ {print dateline; print}   rightday == 1 && /^ORA/ {print}   ' alert_mes.log

 
Jamisar, is soooooo right.
Don't use CSH unless you are a masochist and then don't
inflict it on other people.
 
Hi,marsd
I was forced using C shell. So ....
piggy213
 
Kill the admin????
Nothing personal piggy.
Have a good weekend.
 
csh ON THE COMMAD LINE is for me the best tool you can get.
because of his substitution mechanism, but he (the csh)
to be efficient, needs people who can remember at least
the least 3 command typed in, without using ARRORWS or history or something else.
also people who sure know what they are doing. :)
this is the challance of csh.
the csh-script is a 'miscarriage' i mean 'eine Fehlgeburt'
(look at leo.org for translation if you dont understand me)
in every sh you cat start an other interpreter, use it!
there are a lot of paper explaining WHY you don't should use csh-scripts, look in google for 'why not'
vox clamantis in deserto.
 
hmm ... i guess i just thought that the $TZ would save the day with the TZ thingamy.

only started playing with it in the last 2 weeks ... before that i had an awk script:
Code:
LASTFORTNIGHT=`date &quot;+%y %m %d&quot; | awk '{ split(&quot;31,31,28,31,30,31,30,31,31,30,31,30&quot;,month,&quot;,&quot;); if ($1 % 4 == 0) {month[3]=29;}; day=$3-14; year=$1+0; mon=$2+0; if (day <= 0) {     day+=month[$2-0]; mon=$2-1;     if (mon==0) {year=$1-1; mon=12;} } printf(&quot;%02d/%02d/%02d&quot;,day,mon,year); }'`

note the 14 is the number of days.

guess it wouldn't take too much effort to change.
 
Jad: good script! As you can see from reading Piggy123's other thread, I thought the TZ thing was great too until I actually started playing with it!

Piggy123: If you would like to use Jad's date script, a few changes are needed, since you need the month by name rather than number. I suggest this:
Code:
date &quot;+%y %m %d&quot; | nawk '{    split(&quot;31,31,28,31,30,31,30,31,31,30,31,30&quot;, mdays,&quot;'&quot;);   split(&quot;Dec,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec&quot;,mname,&quot;'&quot;);   if ($1 % 4 == 0) mdays[3]=29;   day=$3+0; mon=$2+0; yesday=day-1;   if (yesday > 0) {yesmon=mon} else {yesmon=mon-1; yesday=mdays[yesmon]};   print mname[mon], day, mname[yesmon], yesday;   } ' | read month day yesmonth yes

Warning: keep the &quot;+0&quot;. It looks like it does nothing, but in fact it tells the computer that you want day and mon to be numbers and not strings.
 
Hi Daedelus,
Sorry,the program was a little bit difficult to me. I don't understand from line three($1 % 4...) through the bottom. Could you explain to me if you have time? Thank you very much!

piggy
 
the $1 % 4 is 1 modulus 4 ... i.e. what is returned after you divided $1 by 4 ...

Code:
e.g. 21 % 4 = (21 - (int(21 / 4) * 4))
            = (21 - (int(5.25) * 4))
            = (21 - (5 * 4))
            = (21 - 20)
            = 1

basically it will tell you if a number is the number of a leap year.

--

combine all the above posts to get:

Code:
#!/bin/sh
# get all the dates ...
date &quot;+%y %m %d&quot; | nawk '{    split(&quot;31,31,28,31,30,31,30,31,31,30,31,30&quot;, mdays,&quot;'&quot;);   split(&quot;Dec,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec&quot;,mname,&quot;'&quot;);   if ($1 % 4 == 0) mdays[3]=29;   day=$3+0; mon=$2+0; yesday=day-1;   if (yesday > 0) {yesmon=mon} else {yesmon=mon-1; yesday=mdays[yesmon]};   print mname[mon], day, mname[yesmon], yesday;} ' | read month day yesmonth yes

awk 'BEGIN { rightday = 0 } $2~~ /'$yesmonth'/ && $3 ~~ /'$yes'/ { rightday = 1; print $0 } $2~~ /'$month'/ && $3 ~~ /'$day'/ {exit} rightday == 1 && /ORA/ {print}' alert_mes.log
 
hmm ... anyone else have a problem with that read statement?
could be a thing with solaris but:
Code:
echo &quot;Sep 10 Sep 9&quot; | read month day yesmonth yes ; echo $month $day $yesmonth $yes
gives me a nice blank line
whereas:
Code:
echo &quot;Sep 10 Sep 9&quot; > t.file ; read month day yesmonth yes < t.file ; rm t.file; echo $month $day $yesmonth $yes
returns : [tt]Sep 10 Sep 9[/tt]

anyone?
 
it's NOT a 'read' - it's a PIPE.
A '|' spawns a new shell and you're 'read'-ing your vars in a subshell. The subshells vars do NOT get exported to the parent shell.

You might consider something like that tho:

echo &quot;Sep 10 Sep 9&quot; | ( read month day yesmonth yes ; echo $month $day )

vlad
+---------------------------+
|#include<disclaimer.h> |
+---------------------------+
 
so it should have been:
Code:
#!/bin/sh
# get all the dates ...
date &quot;+%y %m %d&quot; | nawk '{    split(&quot;31,31,28,31,30,31,30,31,31,30,31,30&quot;, mdays,&quot;'&quot;);   split(&quot;Dec,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec&quot;,mname,&quot;'&quot;);   if ($1 % 4 == 0) mdays[3]=29;   day=$3+0; mon=$2+0; yesday=day-1;   if (yesday > 0) {yesmon=mon} else {yesmon=mon-1; yesday=mdays[yesmon]};   print mname[mon], day, mname[yesmon], yesday;} ' | (read month day yesmonth yes ;
awk 'BEGIN { rightday = 0 } $2~~ /'$yesmonth'/ && $3 ~~ /'$yes'/ { rightday = 1; print $0 } $2~~ /'$month'/ && $3 ~~ /'$day'/ {exit} rightday == 1 && /ORA/ {print}' alert_mes.log)
 
Curious. I've used this pipe into read construction several times before without problems. Its the most convient way I know of to set several variables at once. Could it be a difference between ksh, which I habitually work in, and sh or csh? I'm not on a Unix box right now, but I will certainly try Jad's example tomorrow!
 
Okay I just tried the construct
Code:
echo A B C | read a b c; echo $a $b $c
on several shells in /bin. Here are the results I got:
sh: A B C
ksh: A B C
csh: a: Undefined variable.
Rsh: C
bsh: C
psh: A B C
tsh: A B C

Since I was obstensibly writing a csh script above, I definitely agree that I was in error. But I am curious, Jad and Vlad, are you getting something different in the other shells? And if so, does anyone have an idea why this works for me, but not for everybody? I am working under AIX 4.3.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top