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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Nawk question!

Status
Not open for further replies.

piggy213

Programmer
Sep 27, 2002
19
0
0
TW
If I have a file like this:
Sat Sep 28
ORA123: error in xxjob
ORA124: 12345 in xxjob
Sun Sep 29
ORA123: error in xxjob
ORA124: 12346 in xxjob
I wanted to choose today's error message line like:
Sun Sep 29
ORA123:error in xxjob

I can filter today this condition but I don't know how to filter error condition.
ps.Please use nawk in C shell,thanks a lot!
piggy
 
nawk ' BEGIN {
day = sprintf("%s",substr(strftime(),1,10))
}
{
if ($0 ~ day) {
print
getline
print
}
}' filename
 
Hi marsd,

Is strftime() a nawk built-in function, or just gawk?

Grant
 
Hi piggy213,

If strftime() is not available, I think you could use getline to get the system date (using the *nix 'date' command). You might want to use it's format string features, so if you are not familiar with them, you would have to check the man pages (man date).

(Sorry, I would get it for you myself, but I don't access to a *nix system right now -- I don't know the syntax to use the date command's format string feature off the top of my head.)

Grant.
 
Hi Grant,
You are so kind.
Thanks your suggestion.
I am a new to awk and C shell.
May I ask you some questions?

Q1.Should I set array about this part?(But I don't know how many lines in today's message,it's the active and unknown log.)
Sat Sep 28
ORA123: error in xxjob
ORA124: 12345 in xxjob
Q2.nawk '$2 ~ /'$month/ && $3 ~ /'$date'/ {print} n --> 0' infile
The above is one part of my solution about filter today's condition.
How do I find out error line and only print the date and the error line?
Sorry, I apologized cause complications for you.
 
Grant,
You may be right, don't know if nawk has strftime().
Sorry 'bout that. Just assumed it.
 
OTOH
awk '
function tenchartime() {
"date" | getline day
day = substr(day,1,10)
return day
}
{
print tenchartime()
}' < <(echo &quot;&quot;)
Sun Sep 29
 
Hi piggy213,

Well, I think marsd has pretty much given you everything you need, except I think you are saying that the '/error/' line might not necessarily show up on the line immediately following the date.

With that in mind, I wrote the following, but it's totally based on marsd's stuff:

#!/usr/bin/awk -f
function tenchartime()
{
&quot;date&quot; | getline day;
day = substr(day,1,10);
return day;
}

BEGIN{ currentdate=tenchartime(); }

$0 ~ currentdate()
{
print $0;
while( (getline) > 0 )
{
if( $0 ~ /error/ )
{
print $0;
exit;
}
}
}


I can't test this, but I'm pretty sure the idea is right.

Hope this is what you were looking for.
Grant.
 
Hi,

Earlier I mentioned that you could use the Unix/Linux date command with special formatting capabilities. I thought I would take the opportunity to show how they can be used.

First I will show an excerpt from the man page for date (on an AIX box) with an example, then I will show a small program that I think does what piggy213 wants:

Field Descriptors (must be preceded by a %):
a abbreviated weekday name
A full weekday name
b abbreviated month name
B full month name
c country-specific date and time format
d day of month - 01 to 31
D date as %m/%d/%y
e day of month - 1 to 31 (single digits are preceded by a
blank)
h abbreviated month name (alias for %b)
H hour - 00 to 23
I hour - 01 to 12
j day of year - 001 to 366
m month of year - 01 to 12
M minute - 00 to 59
n insert a new-line character
p string containing ante-meridiem or post-meridiem indicator
(by default, AM or PM)
r time as %I:%M:%S %p
R time as %H:%M
S second - 00 to 61, allows for leap seconds
t insert a tab character
T time as %H:%M:%S
U week number of year (Sunday as the first day of the week) -
00 to 53
w day of week - Sunday = 0
W week number of year (Monday as the first day of the week) -
00 to 53
x Country-specific date format
X Country-specific time format
y year within century - 00 to 99
Y year as ccyy (4 digits)
Z timezone name


An generic example:

% date '+DATE: %m/%d/%y%nTIME: %H:%M:%S'
DATE: 09/30/02
TIME: 08:33:39



For our script, we want the date to be formatted like 'Sun Sep 29', so the format specifiers that interest us:

a abbreviated weekday name
b abbreviated month name
d day of month - 01 to 31]


So, the specific format for our date command should be:

date '+%a %b %d'




Our script:

% cat log.awk
#!/usr/bin/awk -f

BEGIN{ &quot;date '+%a %b %d'&quot; | getline date; }

$0 ~ date {
print $0;
while( (getline) > 0 )
{
if( $0 ~ /error/ )
{
print $0;
exit;
}
}
}



Some sample data:

% cat log.txt
Sat Sep 28
ORA123: error in xxjob
ORA124: 12345 in xxjob
Sun Sep 29
ORA123: error in xxjob
ORA124: 12346 in xxjob
Mon Sep 30
ORA123: abcde in xxjob
ORA124: error in xxjob
ORA125: 12345 in xxjob
Tue Nov 1
ORA123: zyxwv in xxjob
ORA124: error in xxjob
ORA125: 12345 in xxjob



To run the awk script to find entries for the current date:

% log.awk log.txt
Mon Sep 30
ORA124: error in xxjob



To run the awk script to find entries for a specific date, pass the value of the date variable on the command line:

% log.awk date='Tue Nov 1' log.txt
Tue Nov 1
ORA124: error in xxjob



Hope this was of some value.
Grant
 
Hi marsd and Grant,
I appreciated your helps.
May I ask another questions?

1).The top of the program which you wrote was &quot;#!/usr/bin/awk -f&quot; , could I add &quot;#!/bin/csh -f&quot; ?
2).Or csh had already include awk? So I could only write &quot;#!/bin/csh -f&quot; in the program.

ps.Today I only wrote &quot;#!/bin/csh -f&quot; in the program but it couldn't work.

Thanks your directions.
 
Hi piggy213,

The top line (#!/usr/bin/awk -f) is called the 'shebang line'.

The shebang line tells the Unix/Linux environment that this is specifically an awk script (as opposed to a Bourne-shell or c-shell script, for example). You need a different shebang line for awk, c-shell, Bourne-shell, Perl, and so on.

The shebang line also tells the Unix/Linux environment how to find the awk program that will be responsible for executing the awk script.

The path that you should use for the shebang line may be different from what I wrote (ie: /usr/bin/awk). To make sure you are using the correct path on your machine, type:
% which awk

You might see something like this:
% which awk
/bin/awk


In that case, you could change the shebang line to:
#!/bin/awk -f



The '-f' switch is an instruction to the awk program that you must include after the shebang line. Anyway, think of it as having a special meaning for awk. If there is a '-f' switch for c-shell, it would probably have an entirely different meaning. So, don't use it with a c-shell script just because I used it with an awk script.


I am guessing that you might want to call the script I created above (log.awk) from a c-shell script. Here is a hint how to do it:

#!/usr/bin/csh
Do something in the c-shell language...
set SEARCHDATE = &quot;Mon Sep 30&quot;
Do something else in the c-shell language...
awk ' BEGIN{ &quot;date '+%a %b %d'&quot; | getline date; }
$0 ~ date {
print $0;
while( (getline) > 0 )
{
if( $0 ~ /error/ )
{
print $0;
exit;
}
}
}' date=$SEARCHDATE log.awk
do some other stuff in the c-shell language...


Hope this answers your questions,
Grant
 
Hi Grant,
I extremely appreciated your help.
Today I tried the program &quot;log.awk&quot;, it could work only in awk environment. If I added it in C shell, it couldn't work. Because it has to be write like this:

#!/bin/csh
nawk -f log.awk log.txt

So thank you very much.

piggy213
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top