LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Awk question - Search, print & replace strings (http://www.linuxquestions.org/questions/linux-newbie-8/awk-question-search-print-and-replace-strings-4175439391/)

shivaa 11-29-2012 09:16 PM

Awk question - Search, print & replace strings
 
Hello everyone!
Q1# I am searching two strings in a log file. Condition is, first it finds string1, then in same line if it finds second string2, it should print the the count of total number of lines.
Code:

awk '/sring1/ && /string2/ {print $11}' example.logs | wc -l
It gives result like:
Code:

123456
5.878u 0.058s 0:05.90 100.3%    0+0k 0+0io 0pf+0w

Since I want to store it in some variable (which must contain a numeric value for further calculation), but the line below count (marked in red color)causing problem. So how can I avoid this extra line in output?

Q2# After printing the lines containing both strings, I want to replace the word contained in $11.
Sample example.log file:
Code:

s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
(Output truncated...)
In output file it will print:
srting2=1234
srting2=1234
srting2=1234...

And I want only numeric values i.e. 1234 (by replacing keyword string2 by 'empty'). So how can I combine both 1st (search and print strings) and 2nd (replace strnig) operations using awk?

druuna 11-30-2012 01:17 AM

First of all: Can you please stop using the larger font, it doesn't make reading easier or makes your point clearer at all. It also makes it harder to quote, having to remove all the (size) codes. I'm not sure what others think but I find it a bit annoying to be honest. (Fixed by OP)

About your questions:
Quote:

Originally Posted by shivaa (Post 4839926)
Hello everyone!
Q1# I am searching two strings in a log file. Condition is, first it finds string1, then in same line if it finds second string2, it should print the the count of total number of lines.
Code:

awk '/sring1/ && /string2/ {print $11}' example.logs | wc -l
It gives result like:
Code:

123456
5.878u 0.058s 0:05.90 100.3%    0+0k 0+0io 0pf+0w

Since I want to store it in some variable (which must contain a numeric value for further calculation), but the line below count (marked in red color)causing problem. So how can I avoid this extra line in output?

It shouldn't print the red line. The output created by awk is piped to wc and the amount of lines (-l checks for newlines) found should be printed (one number).

I did some testing with the example.log given in question 2 and I cannot get it to print a second line, just the count (5 in this case) is printed.

Are you sure the input file is ASCII text and not some other format? (file example.logs to check).


About your second question:

Quote:

Q2# After printing the lines containing both strings, I want to replace the word contained in $11.
Sample example.log file:
Code:

s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
(Output truncated...)
In output file it will print:
srting2=1234
srting2=1234
srting2=1234...

And I want only numeric values i.e. 1234 (by replacing keyword string2 by 'empty'). So how can I combine both 1st (search and print strings) and 2nd (replace strnig) operations using awk?
Is this what you are looking for:
Code:

awk '/string1/ && /srting2/ { gsub(/srting2=/,"",$11 ) ; print $11}'
Have a look here for more info and other (g)awk functions: 9.1.3 String-Manipulation Functions

David the H. 11-30-2012 11:24 AM

For the first action you can do away with wc, and just count the total with awk.

Code:

awk '/sring1/ && /string2/ { n++ } END{ print n }' example.logs
As for the second one, I can't quite understand your description. But I assume that druuna is right when he guessing you just want to remove the "string2=" part from field 11? He's already demonstrated that the gsub function (or in this case, just sub) can be used to remove such substrings.

Finally, am I right that you want to combine these into a single command? This could be problematic, as the output would necessarily contain both the revised text and the number count. Please clarify exactly what you want to do here.

shivaa 12-01-2012 09:18 AM

Hello,
@Druuna: In this file example.log every matching line has simple alphabetic strings in all field, except field 11th. String in $11 has some value against it like:
s0 string1 s1 s2 s3 s4 s5 s6 s7 s8 srting2=1234 s9
So awk will first match both strings, and then will print only string2 i.e. $11 (string2=1234...). Upto this it's working fine. Then in this string2 in 11th field, I want only numeric values (i.e. 1234 etc.). So I want to substitute this "value=" keyword with some empty string, and keep only numeric part.
Following didn't help. Even use of sub function couldn't help.
Quote:

awk '/string1/ && /srting2/ { gsub(/srting2=/,"",$11 ) ; print $11}'
Getting error:
Quote:

awk: syntax error near line 1
awk: illegal statement near line 1
FYI, OS is Solaris 10.5, Awk version couldn't be retrieved.

@David: As you suggested, counting worked fine. Thanks ;)

druuna 12-01-2012 10:23 AM

Its been a while since I worked on a SunOS/Solaris box, but I do remember that more than one awk flavour was available at the time.

nawk (/usr/xpg4/bin/awk if I'm not mistaken) does permit sub and gsub, awk (/usr/bin/awk) does not. It could be that nowadays gawk is also available out of the box, don't know about that though.

Which one are you using?

David the H. 12-02-2012 12:35 PM

Yes, it appears that sub/gsub are not available in basic awk, only nawk/gawk.

http://www.grymoire.com/Unix/Awk.html#uh-40

In this particular case we could instead use the split function, since there's a clearly-defined character to divide the string by.

Code:

awk '/string1/ && /string2/ { split($11,a,"=") ; print a[2] }'
For the best long-term value though you should probably upgrade to one of the more advanced versions of the program.

shivaa 12-06-2012 01:03 PM

Yes! It was a problem with awk (/usr/bin/awk). Everything worked find with nawk (/usr/xpg4/bin/awk).
Thanks a bunch Druuna and David !!


All times are GMT -5. The time now is 06:37 PM.