Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place. |
| Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
10-24-2011, 11:40 AM
|
#1
|
|
LQ Newbie
Registered: May 2005
Posts: 17
Rep:
|
Awk - How to print match instead of whole line
I wish to use awk in order to extract email addresses from a log file. I wrote the proper regular expression, however it prints the whole line, while i want it to only print the match (in my case, the email address). Can it be done?
Here is my code:
tail -f /var/log/mail.log | awk '/\ to=([^@]+@[^,:]+)/ { print $7 }'
... where $7 is useless for my goal, it only serves as something to print during testing.
Please assist.
Panos
Last edited by protocol; 10-24-2011 at 12:41 PM.
|
|
|
|
10-24-2011, 11:58 AM
|
#2
|
|
Senior Member
Registered: Jan 2010
Posts: 1,604
|
Hi,
please provide some sample data. It is hard to guess what is wrong without seeing the input and output.
|
|
|
|
10-24-2011, 12:25 PM
|
#3
|
|
LQ Newbie
Registered: May 2005
Posts: 17
Original Poster
Rep:
|
Of course.
A standard line from my mail server's log looks like this:
Code:
Oct 24 19:20:27 server postfix/pipe[31099]: 236041EA4AC0: to=<g.pavlakis@domain.com>, relay=dovecot, delay=0.81, delays=0.8/0/0/0.01, dsn=2.0.0, status=sent (delivered via dovecot service)
I wish to extract the :
Code:
g.pavlakis@domain.com
however, the awk line i posted will print the seventh segment of the line (which sometimes indeed contains the mail address, but sometimes it does not - for example, postfix might add a couple more segments to the line, making the seventh segment irrelevant). So, what i really need, is for postfix to print what it actually matches, not the nth segment or the complete line that contains the match.
|
|
|
|
10-24-2011, 01:03 PM
|
#4
|
|
Senior Member
Registered: Jan 2010
Posts: 1,604
|
Well, you can surely do this with awk. However, how about a sed solution? It is a bit easier in this case since it is RegEx oriented while awk is field oriented. This worked with your sample:
Code:
sed -r 's/.*to=<([^>]*)>.*/\1/'
This assumes that the address will be inside to=<user@domain >. Also, I notice that you are posting from a Mac in your profile column on the left. If you want to do this on a Mac then we will have to change the sed a bit since the above solution requires GNU sed and as far as I know it is not available by default on a Mac.
|
|
|
|
10-24-2011, 01:07 PM
|
#5
|
|
LQ Newbie
Registered: May 2005
Posts: 17
Original Poster
Rep:
|
Quote:
Originally Posted by crts
Well, you can surely do this with awk. However, how about a sed solution? It is a bit easier in Also, I notice that you are posting from a Mac in your profile column on the left. If you want to do this on a Mac then we will have to change the sed a bit since the above solution requires GNU sed and as far as I know it is not available by default on a Mac.
|
Thanks for noticing: it is something i work on a Linux machine i have at the office (i am connected to it via SSH). So it is not for the Mac.
Will your sed solution allow me to assign the found/matched email address to some variable and call an external script for further processing? I mean, after i find the address, i was thinking that perhaps i could "post" it to some other script for e.g. inserting it in a database or something. Is that possible?
|
|
|
|
10-24-2011, 01:14 PM
|
#6
|
|
Senior Member
Registered: Jan 2010
Posts: 1,604
|
Quote:
Originally Posted by protocol
Will your sed solution allow me to assign the found/matched email address to some variable and call an external script for further processing? I mean, after i find the address, i was thinking that perhaps i could "post" it to some other script for e.g. inserting it in a database or something. Is that possible?
|
Sure. Just call it like
Code:
variable=$(sed -r 's/.*to=<([^>]*)>.*/\1/' filename)
Notice, that there mustn't be any space between variable and the command substitution $().
|
|
|
|
10-24-2011, 01:20 PM
|
#7
|
|
LQ Newbie
Registered: May 2005
Posts: 17
Original Poster
Rep:
|
Lovely.
One thing though.. i run your see code, along with my tail -f (contained in the original one-liner i posted) and it behaves as follows:
a) The first time it matches.. yes it prints the email address alone.
b) All subsequent times it matches, it prints the complete log line that contains the match, exactly as my faulty awk was doing.
Did i miss something? The whole point is that it keeps extracting email addresses as they appear in the log files, in real time.
Panos
|
|
|
|
10-24-2011, 01:26 PM
|
#8
|
|
Senior Member
Registered: Jan 2010
Posts: 1,604
|
Quote:
Originally Posted by protocol
Lovely.
One thing though.. i run your see code, along with my tail -f (contained in the original one-liner i posted) and it behaves as follows:
a) The first time it matches.. yes it prints the email address alone.
b) All subsequent times it matches, it prints the complete log line that contains the match, exactly as my faulty awk was doing.
Did i miss something? The whole point is that it keeps extracting email addresses as they appear in the log files, in real time.
Panos
|
Nope, you did not miss anything. By default, sed prints the entire line. A small modification will correct this:
Code:
variable=$(sed -nr 's/.*to=<([^>]*)>.*/\1/p' filename)
The -n option tells sed to not print anything unless specifically instructed to. The 'p' flag at the end of 's///' does exactly that. It only prints when the 's///' command makes a substitution.
|
|
|
|
10-24-2011, 01:30 PM
|
#9
|
|
LQ Newbie
Registered: May 2005
Posts: 17
Original Poster
Rep:
|
Sincere thanks.
Problem SOLVED.
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 06:43 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|