LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
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 06-12-2012, 02:58 PM   #1
oldfogey
LQ Newbie
 
Registered: Jun 2012
Location: New York City
Posts: 5

Rep: Reputation: Disabled
Locate a field in a record predicated on locating previous value (awk)


Hi,

I have a file with several thousand records. I need to extract the value (from a field) within the records that is not always in the same position but does come after a unique, fixed value.

The records are of variable length - min 9 fields, max 12 fields. Somewhere in the record there's a field that contains the string "host". The very next field in the record is the variable length field whose value I need to extract. For example, the records could look like:

date time value value value value host sys12 secure client MAC status
date time value value host server16 client MAC status
date time value value value value host intl33-a client MAC status

So, from the records shown above I need to extract the values sys12, server16 & intl33-a.

I have only the most basic knowledge of awk but I have to believe there's a straightforward way to extract what I need. Can someone be so kind as to assist?

Thanks in advance for any help you can provide!!
 
Old 06-12-2012, 03:05 PM   #2
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
Code:
[schneidz@hyper ~]$ grep -o host.*" " oldfogey.txt | awk '{print $2}'
sys12
server16
intl33-a
there probably is a way to do it in one awk maybe usng indexes.

edit: here is the awk solution:
Code:
[schneidz@hyper ~]$ awk '
  { for(i=1;i<=NF;i++){
      if ($i ~ /\<host\>/)
          {print $(i+1)} }
}' oldfogey.txt
sys12
server16
intl33-a

Last edited by schneidz; 06-12-2012 at 03:24 PM.
 
1 members found this post helpful.
Old 06-12-2012, 03:16 PM   #3
oldfogey
LQ Newbie
 
Registered: Jun 2012
Location: New York City
Posts: 5

Original Poster
Rep: Reputation: Disabled
Awesome! Works perfectly.

Thanks for the quick response.


Regards,

Anthony
 
Old 06-13-2012, 09:29 AM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Here's a sed solution too:
Code:
sed -rn '/host/ s/.*host ([^ ]+).*/\1/p' infile
BTW, I'd also use a simple string comparison in the awk command, rather than a regex. And you can condense it into a one-liner like this:
Code:
awk '{ for (i=1;i<=NF;i++) { if ($i=="host") { print $(i+1) } } }' infile
 
1 members found this post helpful.
Old 06-13-2012, 11:48 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
Code:
grep -Eo 'host [^ ]*' file | cut -d' ' -f2

awk -F"host " '{print gensub(/ .*/,"","1",$2)}' file

awk 'match($0,/host ([^ ]*)/,f){print f[1]}' file

awk '{split(RT,a);print a[2]}' RS="host [^ ]*" file
 
Old 06-13-2012, 07:28 PM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,369

Rep: Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753
From scheidz:
Code:
grep -o host.*" " oldfogey.txt | awk '{print $2}'
I like; didn't know/realise about the -o option.

Having done some testing for my own edification, I would use
Code:
grep -o " "host" ".*
otherwise it can match the string 'host' with either/both of trailing/prefix non-space chars
Code:
# extended test file
cat t.t
date time value value value value host sys12 secure client MAC status
date time value value host server16 client MAC status
date time value value value value host intl33-a client MAC status
date time value value value value hostx intl33-a client MAC status
date time value value value value zhost intl33-a client MAC status

# orig code match
grep -o host.*" " t.t
host sys12 secure client MAC
host server16 client MAC
host intl33-a client MAC
hostx intl33-a client MAC
host intl33-a client MAC

# new code match
grep -o " "host" ".* t.t
 host sys12 secure client MAC status
 host server16 client MAC status
 host intl33-a client MAC status
 
  


Reply



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] awk: how to print a field when field position is unknown? elfoozo Programming 12 08-18-2010 03:52 AM
awk command line: blank line record sep, new line field sep robertmarkbram Programming 4 02-21-2010 05:25 AM
updating a field in a record through AWK suresh.chola Programming 9 01-18-2010 08:07 AM
awk printing from Nth field to last field sebelk Programming 2 01-08-2010 09:39 AM
DJBDNS DNS RR tried to inherit owner from previous record? keysorsoze Linux - Networking 0 02-09-2008 03:58 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 09:40 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration