Operating System - HP-UX
1757987 Members
2577 Online
108866 Solutions
New Discussion юеВ

Re: Yet another awk question...

 
Jamie Collins
Advisor

Yet another awk question...

Given:

cat file.txt
Start
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith
Stop
Start
id fname lname
-- ----- -----
Stop
Start
id fname lname
-- ----- -----
1 Mark Williams
Stop

cat file.awk
awk '/Start/{x=1;y=0}/Stop/{if (y>3){l[y]="\n"; while(i++
Outputs:

id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith


id fname lname
-- ----- -----
1 Mark Williams



How do I print a line before the header...

eg:

This report was run on Sat. May 1, 2005
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith

This report was run on Sat. May 1, 2005
id fname lname
-- ----- -----
1 Mark Williams

Thanks
9 REPLIES 9
Rodney Hills
Honored Contributor

Re: Yet another awk question...

Use the "BEGIN" clause within awk.

awk 'BEGIN{print "today is something"};/Start/{x=1;y=0}/Stop/{if (y>3){l[y]="\n"; while(i++
HTH

-- Rod Hills
There be dragons...
Jamie Collins
Advisor

Re: Yet another awk question...

That produces the following:

today is something
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith


id fname lname
-- ----- -----
1 Mark Williams

Is there a way to get it to print the header every time it sees Start??
Rodney Hills
Honored Contributor

Re: Yet another awk question...

Whoops, I didn't notice you had it before everyline that starts with "id".

Just add an "if" statement-

awk '/Start/{x=1;y=0}/Stop/{if (y>3){l[y]="\n"; while(i++
-- Rod Hills
There be dragons...
Jamie Collins
Advisor

Re: Yet another awk question...

/Start/{x=1;y=0}/Stop/{if (y>3){l[y]="\n"; while(i++}

produces:

This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
Start fname lname
Start ----- -----
Start John Wayne
Start Bill Smith


This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
Start fname lname
Start ----- -----
Start Mark Williams


This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005

Rodney Hills
Honored Contributor

Re: Yet another awk question...

Whoops again.

If you want it printed when "Start" is found, why not add it their.

awk '/Start/{x=1;y=0; print "This report was run on Sat May 1,2005"}/Stop/{if (y>3){l[y]="\n"; while(i++
-- Rod Hills
There be dragons...
Jamie Collins
Advisor

Re: Yet another awk question...

That works good except when I encounter the blank line:

id fname lname
-- ----- -----

It still prints the header line...

This report was run on Sat May 1, 2005
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith


This report was run on Sat May 1, 2005
This report was run on Sat May 1, 2005
id fname lname
-- ----- -----
1 Mark Williams

Maybe a nested if would work?
Hein van den Heuvel
Honored Contributor

Re: Yet another awk question...

awk '/Start/{x=1;y=0}/Stop/{if (y>3){l[y]="\n"; print "hello"; while(i++
Ah, a continuation of an earlier threat.
That solution came form me.
When it sees 'start', it merely starts counting and remembering
When it sees 'stop' AND has seen enough lines it starts to dump its memory with a while loop.

So, for this new requirement you need to add a print in the 'stop' section, just before executing the while... print.
As per above.

In more readable form:

awk '
/Start/{x=1;y=0}
/Stop/ {if (y>3) {
l[y]="\n";
print "hello";
while(i++ }
x=i=0
}
{l[y]=$0;
y+=x}
'

As an alternative you can also overwrite the 'start' line with the desired header, and have the while loop print it out eventually by tweaking its start and end:

awk '/Start/{x=1;y=0;$0="hello"}/Stop/{if (y>3){l[y]="\n"; while(i<=y){print l[i++]}};x=i=0}{l[y]=$0;y+=x}'

Cheers,
Hein
Tim D Fulford
Honored Contributor

Re: Yet another awk question...

awk 'BEGIN{ print "what ever you want"}; ....'

or pribably a better solution is

perl -ane 'INIT{print "hello world"}; if(/Start/ .. /Stop/) { print "@F\n"}'

but I've recently decided to ditch awk for perl...

Tim
-
Muthukumar_5
Honored Contributor

Re: Yet another awk question...

We can get your required output as,

# awk '/Start/{x=1;y=0}/Stop/{if (y>3){l[y]="\n"; if ($l[1]="id") { print "This report was run on Sat. May 1, 2005" }
> while(i++This report was run on Sat. May 1, 2005
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith


This report was run on Sat. May 1, 2005
id fname lname
-- ----- -----
1 Mark Williams

HTH.
Easy to suggest when don't know about the problem!