2011-01-27 4 views
2

Un fichier journal contient beaucoup de données et est trié en fonction des données et de l'heure. La taille de chaque journal peut varier en taille.Personnalisation de l'affichage du contenu du fichier basé sur le modèle grep

Je veux rechercher un motif spécifique dans le fichier journal et si le motif correspond, il devrait afficher ce journal particulier sur l'écran. Toutes les commandes de shell seraient appréciables.

Exemple de fichier journal: -

07/17/2008 10:24:12.323411 >00.23 
Line 441 of xx file 
Dest IP Address: 192.189.52.255   Source IP Address: 192.189.52.200 

000: 0101 0600 4D8C 444C 0000 0000 C0BD 34C8 
008: C0BD 34C9 C0BD 34C9 0000 0000 FFFF FFFF 


07/17/2008 10:24:12.323549 >000.000138 
    Use req data 

000: 0231 7564 705F 7573 7272 6571 2073 6F63 

07/17/2008 10:24:12.323566 >000.000017 
Local 192.189.52.200 Port 68 : Remote 0.0.0.0   Port 0 

000: 012D             .-    
000: 0000 0000 000A 0002 000A 012D    ...........-  

    0: NULNUL NULNUL NULLF NULSTX NULLF SOH -    

ici si je recherche pour adresse ip 192.189.52.200 particulier. Il doit afficher tout journal des événements comme conséquence,

07/17/2008 10:24:12.323566 >000.000017 
Local 192.189.52.200 Port 68 : Remote 0.0.0.0   Port 0 

000: 012D             .-    
000: 0000 0000 000A 0002 000A 012D    ...........-  

    0: NULNUL NULNUL NULLF NULSTX NULLF -    

Répondre

0

Cela nécessite GNU AWK (gawk) en raison de l'utilisation d'une expression rationnelle pour le séparateur d'enregistrement (RS).

#!/usr/bin/awk -f 
BEGIN { 
    pattern = ARGV[1] 
    delete ARGV[1] 

    # could use --re-interval 
    d = "[0-9]" 
    RS = d d "/" d d "/" d d d d " " d d ":" d d ":" d d "[^\n]*\n" 
} 

NR > 1 && ($0 ~ pattern || rt ~ pattern) { 
    print rt 
    print $0 
} 

{ 
    rt = RT # save RT for next record 
} 

Il est pas joli, mais ça fonctionne.

Exécuter comme ceci:

./script.awk regex logfile 

Exemples:

$ ./script.awk 'C0BD|012D' logfile 

07/17/2008 10:24:12.323411 >00.23 

Line 441 of xx file 
Dest IP Address: 192.189.52.255   Source IP Address: 192.189.52.200 

000: 0101 0600 4D8C 444C 0000 0000 C0BD 34C8 
008: C0BD 34C9 C0BD 34C9 0000 0000 FFFF FFFF 



07/17/2008 10:24:12.323566 >000.000017 

Local 192.189.52.200 Port 68 : Remote 0.0.0.0   Port 0 

000: 012D             .- 
000: 0000 0000 000A 0002 000A 012D    ...........- 

    0: NULNUL NULNUL NULLF NULSTX NULLF SOH - 

$ ./script.awk '10:24:12.323549' logfile 
07/17/2008 10:24:12.323549 >000.000138 

    Use req data 

000: 0231 7564 705F 7573 7272 6571 2073 6F63 
+0

@Dennis: Merci, je me sers Cygwin. Lorsque j'essaie d'exécuter ce script shell, il affiche tout le fichier journal au lieu d'afficher un événement de journal particulier. – Thangaraj

+0

@Thangaraj: Cela fonctionne très bien chez Cygwin. Votre fichier journal a-t-il des fins de ligne Windows ou Unix? Que dit 'awk --version'? En utilisant vos données d'exemple, quelles expressions régulières avez-vous essayé? Les avez-vous cités? –

+0

@Dennis: $ awk --version GNU Awk 3.1.8 ./script.awk $ '10: 24: 12,323549' winLogfile.txt j'enregistrer ce fichier journal en utilisant le bloc-notes et éditeur vi ainsi. Mais le résultat est le même. Toute aide pour résoudre ce problème serait appréciable. – Thangaraj

0

Vous pouvez utiliser -A[n] drapeau avec grep, où nous n le nombre de lignes après le match. par exemple

grep -A6 '192.189.52.200' my.log 

+0

Malheureusement, cela ne fonctionne pas avec l'exigence que chaque entrée soit de différentes longueurs – xaxxon

0

Si vous avez Ruby ou possibilité de l'installer, vous pouvez écrire un script pour analyser les entrées du fichier journal et la correspondance d'impression. Voici un script qui devrait fonctionner:

filename=ARGV[0] 
regexpArg=ARGV[1] 
unless filename and regexpArg 
     puts "Usage: #{$0} <filename> <regexp>" 
     exit(1) 
end 

dateStr='\d\d\/\d\d\/\d\d\d\d' 
timeStr='[0-9:.]+' 
whitespace='\s+' 
regexpStr = dateStr + whitespace + timeStr + whitespace + '>[0-9.]+' 
recordStart=Regexp.new(regexpStr) 
records=[] 
file=File.new(filename, "r") 
addingToRecord = false 
currentRecord = "" 
file.each_line { |line| 
     match = recordStart.match(line) 
     if addingToRecord 
       if match 
         records.push(currentRecord) 
         currentRecord = line 
       else 
         currentRecord += line 
       end 
     else 
       if match 
         addingToRecord = true 
         currentRecord = line 
       end 
     end 
} 
file.close 
regexp=Regexp.new(regexpArg) 
records.each { |r| 
     if regexp.match(r) 
       puts "----------------------------------------" 
       puts r 
       puts "----------------------------------------" 
     end 
} 
Questions connexes