Rob Oravec wrote: > Hi All! Hello,
> Please help this beginner! > More than likely there is an easy way to do this and/or I am doing > something stupid but I just don't know how. > Sorry if this is a bit long. > > (Scenario) > -Several routers/firewalls log events to a single ($log_file). > -I want to be able to seperate the logs based on router/firewall IP > addresses ($log_source) and dump all > matches to their relevant files for further processing ($date-$ip.log) > -Process the ($ip_file) line by line using each line as a regular > expression, processing the ($log_file). > This way if I add more routers/firewalls to the picture then its just a > case of adding a new IP address to the ($ip_file) and not adding regular > expressions to the script. > > ($ip_file) > 10.10.10.1 > 10.10.10.2 > 10.10.10.3 > > ($log_file) > <snipped> > 2005-09-05 00:05:11 Local5.Info 10.10.10.1 %SEC-6-IPACCESSLOGP: > list IN_REF_2 denied tcp xxx.xxx.xxx.xxx(2948) -> xxx.xxx.xxx.xxx(135), > 1 packet > 2005-09-05 00:05:11 Local5.Info 10.10.10.2 %SEC-6-IPACCESSLOGP: > list IN_REF_2 denied tcp xxx.xxx.xxx.xxx(2949) -> xxx.xxx.xxx.xxx(135), > 1 packet > 2005-09-05 00:05:11 Local5.Info 10.10.10.3 %SEC-6-IPACCESSLOGP: > list IN_REF_2 denied tcp xxx.xxx.xxx.xxx(2973) -> xxx.xxx.xxx.xxx(135), > 1 packet > > My result/problem so far: > I think I read the ($ip_file) correctly and then open the ($log_file) to > search through it based on each line in the ($ip_file). > When it has processed the ($log_file) and dumped the results to the > relavant files ($date-$ip.log) it only prints out the last matching line > for each ($log_source) but need it to print all the matches. > > ------------------------------------------------------------start-script > #!/usr/bin/perl Your next two lines should be: use warnings; use strict; They will help you find mistakes and will enforce better programming habits. > ($mday,$mon,$year) = (localtime)[3..5]; > $date = sprintf "%d%02d%02d", $year+1900, $mon+1, $mday; > ($sec,$min,$hour)=localtime(time); > $time = sprintf "%02d:%02d:%02d", $hour, $min, $sec; Why not just make *one* call to localtime() to get all the fields you need? my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime; my $date = sprintf '%04d%02d%02d', $year + 1900, $mon + 1, $mday; my $time = sprintf '%02d:%02d:%02d', $hour, $min, $sec; > $log_dir = "/home/net1/log"; > $rep_dir = "/home/net1/Apache2/htdocs/router-logs"; > $log_file = "$log_dir/$date.log"; > $ip_file = "/home/net1/log/ip.txt"; > > open(IPFILE, "$ip_file") || die "Could not open $ip_file"; There is no need to put quotes around $ip_file as it is already a string. You should include the $! variable in the error message so you know *why* the file would not open. open IPFILE, $ip_file or die "Could not open $ip_file: $!"; > foreach (<IPFILE>) { You are reading the entire file into a list in memory and each subsequent line is assigned to the $_ variable. > @lines = <IPFILE>; The filehandle IPFILE is now at end-of-file so it assigns nothing to @lines. > chomp($ip); You are chomping the $ip variable which has nothing in it the first time through the loop and the previous line's contents for each subsequent iteration. > ($ip) = split; This is short for: ($ip) = split ' ', $_, 2; Which means that you are actually getting the data from $ip_file into the $ip variable. > open (LOGFILE, $log_file) || die "Could not open $log_file"; Because you are inside a foreach loop you have to open this file for every entry in $ip_file, that could really slow down your program if $log_file is large. You should include the $! variable in the error message so you know *why* the file would not open. > while (<LOGFILE>) { ($datestamp, $timestamp, $facility, $log_source, > $restofline) = split (/\s+/, $_); You used split() correctly before, why the change here? Your variable $restofline implies that it will contain the rest of the line after $log_source but that is incorrect, it will contain the next *field* after $log_source. To get the rest of the line into $restofline you have to use the third argument to split(). > if ($log_source =~ /$ip/) { This won't work correctly because $ip contains regular expression meta-characters, specifically the . character which matches any character (except newline.) You need to either use the quotemeta escape: if ($log_source =~ /\Q$ip/) { Or just test for equality: if ($log_source eq $ip) { > $log_new = "$rep_dir/$date-$ip.log"; open(OUT, > ">$log_new") || die "Could not open log_file"; print OUT; You are opening $log_new for output which truncates the file to zero length. You should include the $! variable in the error message so you know *why* the file would not open. > close(OUT); > print; > } } > } close(IPFILE); > close(LOGFILE); > ------------------------------------------------------------stop-script > Comment/s: > The search has to be against the ($log_source) variable as the IP > address may appear more than once in the same line and meaning something > completely different. > > Other things I have tried: > I have tried using the append option when opening ($log_new) and works > great on the first go, then obviously it appends the next go round. I don't understand why you are saying that the append option does not work correctly. What exactly are you trying to accomplish? John -- use Perl; program fulfillment -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>