Helmut: erweitertes Grep

Hallo,

habe hier ein perl script dem ich eine log Datei beim ausführen mitgebe und zugleich die ausgabe Log mitteile.

usage: ip2fqdn.pl < logfile > new-logfile

Hier das Script:

  
#!/usr/bin/perl  
### -------------------------------------------------------------------- ###  
#  
# ip2fqdn.pl: converts logs with IP numbers in the first line position  
#             to fully qualified domain names  
#  
# usage: ip2fqdn.pl < logfile > new-logfile  
#  
# Author: Martin Gleeson, July 1996.  Public domain.  
#  
# Bug fixes: Neil Murray <neil@aone.com.au>  
#            - The wrong FQDN given to an IP address if the IP address  
#            had only 1 digit in the first two sections of the dotted quad.  
#  
### -------------------------------------------------------------------- ###  
#   The program looks up IP numbers, and keeps the returned IP names in  
#   an associative array, indexed by IP number. This means only one DNS  
#   lookup is made for each distinct IP number, making the whole operation  
#   *reasonably* fast (hey, it's perl, not C :-).  
### -------------------------------------------------------------------- ###  
  
$address_type=2;  
  
while( <STDIN> )  
{  
    chop;  
    ($host, $rest) = /^(\S+) (.+)$/;  
  
    # no need to look it up if it's already been done.  
    if( $hosts{$host} )  
    {  
        $name = $hosts{$host};  
    }  
    else  
    {  
        # new IP number - look for its IP name  
        if($host =~ /\d+\.\d+\.\d+\.\d+/)  
        {  
            @address = split(/\./,$host);  
            $addpacked = pack('C4',@address);  
            ($name,$aliases,$addrtype,$length,@addrs) =  
                gethostbyaddr($addpacked,$address_type);  
        }  
        # if nothing returned, then no IP name exists for the IP number  
        $name = $host if ($name eq "");  
  
        # make the IP name lowercase for uniformity  
        $name = "\L$name";  
  
        # add the IP name to the associative array  
        $hosts{$host} = $name;  
    }  
  
    print "$name $rest\n";  
}  
  
exit(0);  

Hier die ersten zeile der Log die ich mit gebe:

  
1306492340\.398    309 10.155.100.27 TCP_MISS/200 330 GET http://api.bing.com/qsonhs.aspx? - DIRECT/62.214.9.149 application/json  
1306492340\.398    163 10.155.100.27 TCP_MISS/200 3340 GET http://de.msn.com/ajax/hpcStub.aspx? - DIRECT/94.245.115.205 text/html  
1306492340\.577     56 10.155.100.27 TCP_MISS/200 493 GET http://cdn.eyewonder.com/100125/769997/1489645/ewtrack.gif? - NONE/- image/gif  

Das script ließt einfach nur zeile für zeile ein wandelt die IP zum Hostname und speichert wieder ab. Es funktioniert auch einwandfrei solange die IP an erster stelle steht.

Leider musste ich die Log umbauen und somit steht sie nun an dritter stelle.

Hier nun zu meinen Proplem.
Sorry am in Perl bin ich ne totale niete.

Hier wird doch die zeile auf bereitet und gegrept. Wie sag ich hier das sich die IP an dritter stelle befindet?

  
($host, $rest) = /^(\S+) (.+)$/;  

Danke schonmal für eure Hilfe.

  1. hi,

    Sorry am in Perl bin ich ne totale niete.

    Warum muss es denn auch Perl sein ;)

    (ehe ichs vergesse: chop haut das letzte Zeichen weg, wahrscheinlich sollte es eher chomp heißen, was einen Zeilenumbruch entfernt)

    Also, Du köntest wie gehabt, zeilenweise durchgehen und die Zeile an \s+ splitten (ein oder mehrere Leerzeichen):

    chomp $zeile;
    my @parts = split /\s+/, $zeile; # splitte an Leerzeichen

    dann findest Du die Einzelteile in [0] bis [-1] (Array).

    Hotti

  2. Viel schlauer ist es doch, eine flüchtige Kopie zu erstellen, mit der das herkömmliche Werkzeug zurechtkommt. Besorge dir auch eine moderne Version davon.

    <access.log perl -MRegexp::Common=net -MRegexp::IPv6='$IPv6_re' -lne'/($RE{net}{IPv4}|$IPv6_re)/; print "$1 $_"' | /usr/sbin/logresolve.pl2 >access.log.resolved