LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-11-2011, 11:04 AM   #1
cristalp
Member
 
Registered: Aug 2011
Distribution: Linux Mint
Posts: 103

Rep: Reputation: Disabled
AWK: match multiple strings in the file, print 1 when match and 0 when not


Dear Experts,

I just want to achieve a very simple function by awk that when there matchs a string "A" or "B" in the file, print 1 otherwise print 0.

How could I do this simply without if else?
 
Old 11-11-2011, 11:34 AM   #2
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Do you want to match both the string or at least one of them? And must the strings be in the same line or can they be on different lines?

This one matches both the strings on different lines:
Code:
awk '/A/{one=1}/B/{two=1}END{print (one+two==2)}' file

Last edited by colucix; 11-11-2011 at 11:35 AM.
 
Old 11-11-2011, 11:54 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,008

Rep: Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193
Alternative:
Code:
awk '/A|B/{print "1";exit}END{print "0"}' file
 
2 members found this post helpful.
Old 11-11-2011, 05:13 PM   #4
cristalp
Member
 
Registered: Aug 2011
Distribution: Linux Mint
Posts: 103

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by colucix View Post
Do you want to match both the string or at least one of them? And must the strings be in the same line or can they be on different lines?

This one matches both the strings on different lines:
Code:
awk '/A/{one=1}/B/{two=1}END{print (one+two==2)}' file
Thanks! But I just want to match one of them. "A" OR "B". I mean, as long as there is string match "A" or "B", I got a print out 1. If there is there is neither "A" nor "B" in the file, print 0.
 
Old 11-11-2011, 10:16 PM   #5
Linux_Kidd
Member
 
Registered: Jan 2006
Location: USA
Posts: 737

Rep: Reputation: 78
a tad better (but slower), easy to mod.
Code:
awk 'BEGIN { count=0;} $0 ~ /(A)|(B)/ { count++; } END { print "Number of times the patterns were seen =",count;}' infile
 
1 members found this post helpful.
Old 11-12-2011, 02:01 AM   #6
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by cristalp View Post
Thanks! But I just want to match one of them. "A" OR "B". I mean, as long as there is string match "A" or "B", I got a print out 1. If there is there is neither "A" nor "B" in the file, print 0.
A slight modification to the suggested code: put >=1 in place of ==2. Easy.
 
Old 11-15-2011, 08:10 AM   #7
cristalp
Member
 
Registered: Aug 2011
Distribution: Linux Mint
Posts: 103

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by grail View Post
Alternative:
Code:
awk '/A|B/{print "1";exit}END{print "0"}' file
Thank you for your code. I tired it. When there is no A and no B in my file, the output is "0" which is what I want. But when there is a A or B in my file, the output is
Code:
1
0
which has a redundant "0" at newline. That is not what I want.

I think your code is the easiest to understand. I don't know where it is wrong, may be the "exit"? Do you have any ideas.
Thanks anyway!
 
Old 11-15-2011, 08:23 AM   #8
cristalp
Member
 
Registered: Aug 2011
Distribution: Linux Mint
Posts: 103

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by colucix View Post
A slight modification to the suggested code: put >=1 in place of ==2. Easy.
Thank you! It works. Could you explain a bit what the meaning of print (one+two>=1)?

what I understood is, this code search A and B separately. If it find a string match "A" it send 1 to variable "one", if it find a string match "B" it send 1 to variable "two". So, if there is no match what value would be send to "one" and "two"? Is that 0??

And then print the result for one+two if one+two larger or equal then 1. So, if there are both "A" and "B" found in the file, one+two should equal to 2, why the output is still 1 in this case?

Or, if there is no "A" and no "B" in the file, own+two now is smaller than 1, why AWK is still able to print 0?

My understanding for the meaning of print (one+two>=1) must be wrong, so what is its correct meaning?
Thanks!!!
 
Old 11-15-2011, 08:31 AM   #9
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by cristalp View Post
Could you explain a bit what the meaning of print (one+two>=1)?

what I understood is, this code search A and B separately. If it find a string match "A" it send 1 to variable "one", if it find a string match "B" it send 1 to variable "two". So, if there is no match what value would be send to "one" and "two"? Is that 0??
Yes. In AWK an uninitialized variable has value 0 if treated arithmetically, is a null string otherwise. The operation one+two causes the variables to be numeric.
Quote:
Originally Posted by cristalp View Post
And then print the result for one+two if one+two larger or equal then 1. So, if there are both "A" and "B" found in the file, one+two should equal to 2, why the output is still 1 in this case? Or, if there is no "A" and no "B" in the file, own+two now is smaller than 1, why AWK is still able to print 0?
The expression is a logical statement which in awk translates to 0 (false) or 1 (true). This is common to many other scripting languages: if you print out a logical variable or expression you will see 0 or 1.
 
1 members found this post helpful.
Old 11-15-2011, 08:36 AM   #10
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by cristalp View Post
I don't know where it is wrong, may be the "exit"? Do you have any ideas. Thanks anyway!
On behalf of grail, I can tell that indeed the exit statement is the problem. The logic is correct (as soon as it encounters A or B the program should print out 1 and exit, without further processing). However in awk the exit statement doesn't prevent the execution of the END block (if present). A slightly different approach, similar to mine could be:
Code:
awk '/A|B/{var=1}END{print var+0}' file
The notation var+0 is necessary to print out the value of 0. Try to remove the +0 part and see the difference.
 
1 members found this post helpful.
Old 11-15-2011, 09:57 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,008

Rep: Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193
Sorry about that ... it was 3am and wasn't paying attention Thank you to colucix for the altered solution
 
Old 11-15-2011, 10:06 AM   #12
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by grail View Post
Sorry about that ... it was 3am and wasn't paying attention
We forgive you!
 
Old 11-15-2011, 10:18 AM   #13
cristalp
Member
 
Registered: Aug 2011
Distribution: Linux Mint
Posts: 103

Original Poster
Rep: Reputation: Disabled
Thanks for colucix's excellent explanations and the help from grail and Linux_Kidd, all together I get a deeper understanding for AWK at the end. Thanks a lot for your patient and kind teaching.
 
  


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 match instead of whole line protocol Linux - General 8 10-24-2011 01:30 PM
[SOLVED] Can not match strings that appear to be identical dnoob Programming 4 02-27-2011 11:42 AM
Sed/Awk: print lines between n'th and (n+1)'th match of "foo" xaverius Programming 17 08-20-2007 11:39 AM
grep/sed/awk - find match, then match on next line gctaylor1 Programming 3 07-11-2007 08:55 AM
a script to match 2 ip strings nass Slackware 2 05-30-2007 03:49 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:18 PM.

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