LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 10-02-2011, 03:24 PM   #1
wolverene13
Member
 
Registered: May 2010
Location: Matiland, FL
Distribution: Debian Squeeze
Posts: 49

Rep: Reputation: 0
AWK print line only if next line matches a string


Hi,

I am relatively new to awk and I was searching all over the place for the answer to this, but can't really find anything valid. I was wondering how to only print a line if the next line matches a string.

I started with something like this:

NODE_1
port 1
description blah
port 2
description blah blah
NODE_2
port 1
description blah
port 2
description blah
NODE_3
port 1
port 2
NODE_4
port 1
port 2
NODE_5
port 1
port 2
NODE_6
port 1
description blahdy blah
port 2
description floop-a-doop

Originally my intention was to exclude any ports that don't have descriptions, while leaving the node names intact.

I've tried:
Code:
awk '/^NODE/;{print};/^description/;{print x; print};{x=$0}'
...to print all "NODE" lines and any "description" line as well as the previous "port" line above it (kudos to crts for that answer).

Now I get this:

NODE_1
port 1
description blah
port 2
description blah blah
NODE_2
port 1
description blah
port 2
description blah
NODE_3
NODE_4
NODE_5
NODE_6
port 1
description blahdy blah
port 2
description floop-a-doop

Which I thought was what was needed, but apparently we don't need the node names of devices that have ports without descriptions at all. So I essentially need to get rid of the node names that are not followed by the string "port". Desired output should look like this:

NODE_1
port 1
description blah
port 2
description blah blah
NODE_2
port 1
description blah
port 2
description blah
NODE_6
port 1
description blahdy blah
port 2
description floop-a-doop

Any help would be greatly appreciated, and if it would help, I can post the actual content rather than all the "blahs" everything if that helps.

Thanks in advance!

Last edited by wolverene13; 10-02-2011 at 03:39 PM. Reason: code example had incorrect variable names
 
Old 10-02-2011, 03:40 PM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,973
Blog Entries: 11

Rep: Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879
Code:
awk '/^port/{port=$0}/^description/{print port;print $0}' nodes
port 1
description blah
port 2
description blah blah
port 1
description blah
port 2
description blah
port 1
description blahdy blah
port 2
description floop-a-doop
Works as desired w/ the current data sample.
 
Old 10-02-2011, 03:51 PM   #3
wolverene13
Member
 
Registered: May 2010
Location: Matiland, FL
Distribution: Debian Squeeze
Posts: 49

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by Tinkster View Post
Code:
awk '/^port/{port=$0}/^description/{print port;print $0}' nodes
port 1
description blah
port 2
description blah blah
port 1
description blah
port 2
description blah
port 1
description blahdy blah
port 2
description floop-a-doop
Works as desired w/ the current data sample.
That looks like it would work, but it doesn't appear to print the node names - while I need the ports and their descriptions, I do also need the node name listed before each set of ports and their respective descriptions.
 
Old 10-02-2011, 04:02 PM   #4
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,973
Blog Entries: 11

Rep: Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879
Quote:
Originally Posted by wolverene13 View Post
That looks like it would work, but it doesn't appear to print the node names - while I need the ports and their descriptions, I do also need the node name listed before each set of ports and their respective descriptions.
Oops - easy fix.
Code:
awk '/^NODE/{print $0}/^port/{port=$0}/^description/{print port;print $0}' nodes
NODE_1
port 1
description blah
port 2
description blah blah
NODE_2
port 1
description blah
port 2
description blah
NODE_3
NODE_4
NODE_5
NODE_6
port 1
description blahdy blah
port 2
description floop-a-doop
 
Old 10-02-2011, 04:08 PM   #5
wolverene13
Member
 
Registered: May 2010
Location: Matiland, FL
Distribution: Debian Squeeze
Posts: 49

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by Tinkster View Post
Oops - easy fix.
Code:
awk '/^NODE/{print $0}/^port/{port=$0}/^description/{print port;print $0}' nodes
NODE_1
port 1
description blah
port 2
description blah blah
NODE_2
port 1
description blah
port 2
description blah
NODE_3
NODE_4
NODE_5
NODE_6
port 1
description blahdy blah
port 2
description floop-a-doop
Well, that's kind of back to square 1; Essentially I need a way to make NODE_3, NODE_4, and NODE_5 go away because they don't have any ports with descriptions on them.

EDIT: Essentially I need something that says: "If the next line after NODE does not begin with "port", don't print NODE either."

Last edited by wolverene13; 10-02-2011 at 04:36 PM. Reason: clarification
 
Old 10-03-2011, 01:18 PM   #6
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,973
Blog Entries: 11

Rep: Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879
Quote:
Originally Posted by wolverene13 View Post
Well, that's kind of back to square 1; Essentially I need a way to make NODE_3, NODE_4, and NODE_5 go away because they don't have any ports with descriptions on them.

EDIT: Essentially I need something that says: "If the next line after NODE does not begin with "port", don't print NODE either."
That description is actually wrong. What you want is: "If the line after port isn't description
don't print node and port either."
Code:
awk '/^NODE/{node=$0}/^port/{port=$0}/^description/{if(prev!=node){print node};print port;print $0;prev=node}' nodesNODE_1
port 1
description blah
port 2
description blah blah
NODE_2
port 1
description blah
port 2
description blah
NODE_6
port 1
description blahdy blah
port 2
description floop-a-doop

Cheers,
Tink
 
Old 10-03-2011, 01:55 PM   #7
wolverene13
Member
 
Registered: May 2010
Location: Matiland, FL
Distribution: Debian Squeeze
Posts: 49

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by Tinkster View Post
That description is actually wrong. What you want is: "If the line after port isn't description
don't print node and port either."
Code:
awk '/^NODE/{node=$0}/^port/{port=$0}/^description/{if(prev!=node){print node};print port;print $0;prev=node}' nodes
NODE_1
port 1
description blah
port 2
description blah blah
NODE_2
port 1
description blah
port 2
description blah
NODE_6
port 1
description blahdy blah
port 2
description floop-a-doop

Cheers,
Tink
Perfect! That's exactly what I needed! Thanks a lot!!

I'd hate to bother you, but if I'm understanding the syntax right:

awk '/^NODE/{node=$0} is essentially "search for lines beginning with "NODE" and "remember" those lines in $0 and collectively call them "node""

/^port/{port=$0} is pretty much the same thing, except searching for lines containing "port", which then join all the "NODE" lines in $0, and collectively called "port"

This is where it gets fuzzy for me:
/^description/{if(prev!=node){print node};print port;print $0;prev=node}'

Does that mean "search for lines beginning with "description", create a variable that is called "prev", then if prev does not equal anything in "node", print everything in "node", print everything in "port", and everything "remembered" in $0" then prev=node? Sorry if that's way off, but I'm fairly new to awk and like to actually learn what I'm doing, rather then just regurgitate the answers that I receive. Thanks for the help!
 
Old 10-03-2011, 02:15 PM   #8
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,973
Blog Entries: 11

Rep: Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879
Quote:
Originally Posted by wolverene13 View Post
Perfect! That's exactly what I needed! Thanks a lot!!

I'd hate to bother you, but if I'm understanding the syntax right:

awk '/^NODE/{node=$0} is essentially "search for lines beginning with "NODE" and "remember" those lines in $0 and collectively call them "node""

/^port/{port=$0} is pretty much the same thing, except searching for lines containing "port", which then join all the "NODE" lines in $0, and collectively called "port"
Not quite ... there's no "collective" there. port and node are variables
that will get populated every time a line begins w/ NODE or port, respectively.
The whole string of expressions gets applied to each line of your nodes file.



Quote:
Originally Posted by wolverene13 View Post
This is where it gets fuzzy for me:
/^description/{if(prev!=node){print node};print port;print $0;prev=node}'

Does that mean "search for lines beginning with "description", create a variable that is called "prev", then if prev does not equal anything in "node", print everything in "node", print everything in "port", and everything "remembered" in $0" then prev=node? Sorry if that's way off, but I'm fairly new to awk and like to actually learn what I'm doing, rather then just regurgitate the answers that I receive. Thanks for the help!
The prev variable and its comparison against node are there so we don't
print NODE for each port line w/ a description, in other words to avoid
the following output:
Code:
NODE_1
port 1
description blah
NODE_1
port 2
description blah blah
NODE_2
port 1
description blah
NODE_2
port 2
description blah
NODE_6
port 1
description blahdy blah
NODE_6
port 2
description floop-a-doop


HIH.


Cheers,
Tink
 
Old 10-03-2011, 03:32 PM   #9
wolverene13
Member
 
Registered: May 2010
Location: Matiland, FL
Distribution: Debian Squeeze
Posts: 49

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by Tinkster View Post
Not quite ... there's no "collective" there. port and node are variables
that will get populated every time a line begins w/ NODE or port, respectively.
The whole string of expressions gets applied to each line of your nodes file.





The prev variable and its comparison against node are there so we don't
print NODE for each port line w/ a description, in other words to avoid
the following output:
Code:
NODE_1
port 1
description blah
NODE_1
port 2
description blah blah
NODE_2
port 1
description blah
NODE_2
port 2
description blah
NODE_6
port 1
description blahdy blah
NODE_6
port 2
description floop-a-doop


HIH.


Cheers,
Tink
Perfect! Thanks again!!
 
  


Reply

Tags
awk, exclude, match, previous


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Insert line using sed or awk at line using line number as variable sunilsagar Programming 11 02-03-2012 10:48 AM
Awk question (How to print a line other than the first or the last line) maxxum600si Programming 5 10-15-2009 11:48 AM
need to delete a line if a field of that line matches using awf in bash scripting accesskarthi Linux - Newbie 8 06-29-2009 03:15 AM
Regex Question: Only print part of line that matches TheMeteorPolice Programming 5 01-12-2006 01:21 PM


All times are GMT -5. The time now is 01:24 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration