ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
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.
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.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi all,
I have a file with patterns like the one hereafter, patterns begin and end with ======, there are many lines inside a pattern. It's a log and what I want to do is to check every pattern to look if the string ERROR exists and if so print that string and the date, hour and Reference contained in the pattern.
I need help to write the script shell.
Thanks in advance
Consty
======
05/02/2007 04:51:02 [8714]: abdndala.c01.07: SAMS can not be sent, TYPE=DOUBE, STATE: 342184546 (slipt 6,Entity:ANY).
ERROR: 4685 Reference :=172910706273
absolute MM :=)(A1225:clAd=0000)(29746:messi :=624020100762629)(2747:hel_lang=3)(K2749:
sams_id=398)
======
try to read some information about sed and grep commands. they are great text filtering and searching tools. google and sed and grep and you'll get the results you need. post the log file if you can.
the best i can think off for now if trying the following:
The problem with grep is that it's exclusively line-based. He needs to know the date and time, but these are contained on a line that comes before the one that tells him if he needs to keep that information at all. This is a situation where Perl comes in really handy. Not knowing the fully syntax of the log file, here's a simple script I came up with:
Code:
#!/usr/bin/env perl
use warnings;
use strict;
my $line = readline STDIN;
while (defined $line) {
if ($line =~ m!======!) {
my $date = '';
my $time = '';
my $error = 0;
my $reference = '';
$line = readline STDIN;
while (defined $line && $line !~ m!======!) {
if ($line =~ m!(\d\d/\d\d/\d\d\d\d) (\d\d:\d\d:\d\d)!) {
$date = $1; $time = $2;
}
elsif ($line =~ m!^ERROR!) {
$error = 1;
$line =~ m!Reference :=(\d+)!;
$reference = $1;
}
$line = readline STDIN;
}
if ($error) {
print "ERROR: date = $date | time = $time | reference = $reference\n";
}
}
else {
$line = readline STDIN;
}
}
This is the log file I used for testing:
Code:
======
05/02/2007 04:51:02 [8714]: abdndala.c01.07: SAMS can not be sent, TYPE=DOUBE, STATE: 342184546 (slipt 6,Entity:ANY).
ERROR: 4685 Reference :=172910706273
absolute MM :=)(A1225:clAd=0000)(29746:messi :=624020100762629)(2747:hel_lang=3)(K2749:
sams_id=398)
======
05/03/2007 04:51:02 [8714]: blahblah.c01.07: SAMS can not be sent, TYPE=DOUBE, STATE: 342184546 (slipt 6,Entity:ANY).
ERROR: 4685 Reference :=12345678
absolute MM :=)(A1225:clAd=0000)(29746:messi :=624020100762629)(2747:hel_lang=3)(K2749:
sams_id=398)
======
05/03/2007 04:51:02 [8714]: foobar.c01.07: SAMS sent successfully, TYPE=DOUBE, STATE: 342184546 (slipt 6,Entity:ANY).
absolute MM :=)(A1225:clAd=0000)(29746:messi :=624020100762629)(2747:hel_lang=3)(K2749:
sams_id=398)
======
Where the first two contain errors and the last one doesn't. Even if that's not quite correct, the script may still work right.
The problem with grep is that it's exclusively line-based.
Actually, grep can be used in this case as well using the -B option to print out lines that occur before the match occurs (-A if you want lines after you match). Ex:
Code:
#!/bin/bash
# Create the error listing. By default, grep
# will separate the lines with a '--' string
error_string=$(grep -B 1 "ERROR" log.file)
# Loop through the error_string variable until
# there is no more information in it.
while [ ${#error_string} -gt 0 ]
do
# Pull out the first error string
error_string2=${error_string%%--*}
# Remove the first error string, enclose in double
# quotes to handle slashes
error_string=${error_string//"${error_string2}"/}
# Remove the -- from the string. Can not be done
# on the previous line as there is no -- at the
# end of the string, and you end up in an
# infinite loop
error_string=${error_string/--/}
# echo out the date, time, error, and reference
echo $(echo ${error_string2} | cut -d' ' -f1,2) ERROR$(echo ${error_string2##*ERROR})
done
This is obviously not the best way to parse the error log (a big log would totally crush this code to the point of it being unusable, trust me), and would suggest using one pearl or sed as mentioned, but wanted to point out that grep can be used for more than displaying just the line that matches your text.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.