1826055 Members
4524 Online
109690 Solutions
New Discussion

Re: help with awk

 
SOLVED
Go to solution
Jamie Collins
Advisor

help with awk

I am doing pattern searches with a 'start' and 'stop' string and want to manipulate the data inside the result set. Need to know how to do this for multiple result sets returned from the search...
15 REPLIES 15
Tom Danzig
Honored Contributor

Re: help with awk

Since you site no specific examples, I'll be quite general.

I would do this in two parts. First gleen out the text you want via the start/stop parameters to a temp file. Then awk the temp file contents as necessary to achive the desired output.


Jamie Collins
Advisor

Re: help with awk

Here is an example...

file:

Start
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith
Stop
Start
id fname lname
-- ----- -----
Stop
Start
id fname lname
-- ----- -----
1 Mark Williams
Stop


I don't want the 'chunk' with no names in it.
awk:

/Start/,/Stop/ {print}


Thanks
Muthukumar_5
Honored Contributor

Re: help with awk

We can do this as,

# cat > testfile
hai test
start
testfile
okei content
itrc forum
stop
over

# awk '/start/,/stop/ { print $0 }' testfile
start
testfile
okei content
itrc forum
stop

If you want to get only contents inside limit exactly then,

# awk '/start/,/stop/ { if ( $0 != "start" && $0 != "stop" ) print $0 }' testfile
testfile
okei content
itrc forum

It will give you the way there.

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

Re: help with awk

if you just want the lines with names on it, and as in your example those lines start with a number, then

awk '$1 ~ /[0-9]*/ {print $0;}'
Jamie Collins
Advisor

Re: help with awk

Based on:

Start
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith
Stop
Start
id fname lname
-- ----- -----
Stop
Start
id fname lname
-- ----- -----
1 Mark Williams
Stop


I need the output to look like this:

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

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

Thanks
c_51
Trusted Contributor

Re: help with awk

awk '
/start/ {
# set print flag, don't print this line
flag=1;}
/stop/ {
#unset print flag, don't print this line
flag=0;
#print blank line
print "";}
{print $0;}' yourFile

a uncommented version

awk '/start/{flag=1;}
/stop/ {flag=0;print "";}
{print $0;}'
c_51
Trusted Contributor

Re: help with awk

oops

this {print $0;}'

should have been

{if ( flag == 1 ) print $0;}'
Jamie Collins
Advisor

Re: help with awk

I get the following:

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

Stop
Start
id fname lname
-- ----- -----

Stop
Start
id fname lname
-- ----- -----
1 Mark Williams

Stop


Same as before but with a space before the Stop... Is there any way awk can process the 'chunk' one at a time... I know that if there are no names in the list it returns 4 rows... the Start and Stop, the header and the dashes... I can't check if the NR is 4 just for each search?
c_51
Trusted Contributor

Re: help with awk

and of course the if (flag
needs to be before the /start/

awk '/start/{flag=1;}
/stop/ {flag=0;print "";}
{print $0;}'

should be

awk 'BEGIN {flag=0)
{if ( flag == 1 ) print $0;}
/start/ {flag = 1;}
/stop/ {flag = 0;print "";}'

oh boy what was i thinking before
better go home before i ...

Jamie Collins
Advisor

Re: help with awk

Since we've updated it a few times.. I'll just paste what I have and where it sits...

>cat dummy3.out
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 dummy3.awk
BEGIN {flag=0}
{if ( flag == 1 ) print $0;}
/Start/ {flag = 1;}
/Stop/ {flag = 0;print "";}


>awk -f dummy3.awk dummy3.out
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith
Stop

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

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



Thanks
c_51
Trusted Contributor

Re: help with awk

change

{if ( flag == 1 ) print $0;}


to

{if ( flag == 1 && $1 !~ "stop" ) print $0;)


sorry for all the incorrect scripts

should have tested before typing
Hein van den Heuvel
Honored Contributor

Re: help with awk


Something like this?


awk 'BEGIN{xx=0}/Start/{x=1}/Stop/{if (xx>3){for(i=0;i
Store each line seen in array l[], incrementing index by x which may be 0 or 1.

Only after seeing start, set array index increment x to 1

When seeing stop, print all array lines if there are enough.

When seeing stop clear increment.


Cheers,
Hein.
Trevor Dyson
Trusted Contributor

Re: help with awk

Try this:

INPUT DATA
$ cat infile
Start
id fname lname
-- ----- -----
1 John Wayne
102982 Bill Smit
Stop
Start
id fname lname
-- ----- -----
Stop
Start
id fname lname
-- ----- -----
1 Mark Williams
Stop

AWK CODE:
$ awk '/^[[:digit:]]+ /' infile

RESULT:
1 John Wayne
102982 Bill Smith
1 Mark Williams
I've got a little black book with me poems in
Trevor Dyson
Trusted Contributor

Re: help with awk

...or if you want to be certain only matched between the Start and Stop flags are shown:


awk ' /Start/,/Stop/ { if(match($0,/^[[:digit:]]+ /)) print $0 }' infile
I've got a little black book with me poems in
Hein van den Heuvel
Honored Contributor
Solution

Re: help with awk

Hey Trevor, from the sample Jamie provided he want to print the header also. So you need to build in a bit oof memory, and/or just hardcode the header and add a 'header printed' flag.

Looking back my example printed too much (I misread an other example to mean that the start and stop line would be needed.

Here is an other try:

awk '/Start/{x=1;y=0}/Stop/{if (y>3){l[y]="\n"; while(i++
This outputs:
id fname lname
-- ----- -----
1 John Wayne
2 Bill Smith


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