2012-04-04 6 views
1

Das sollte ziemlich einfach sein, aber ich habe ein Problem mit dem Fluss eines Awk-Skript. Ich führe das folgende Skript aus und es druckt die Ausgabe immer und immer wieder (wenn ich raten müsste, würde ich sagen, dass es einmal für jede Zeile der Eingabedatei druckt). Wie gewünscht, hier einige gefälschte Eingabe:Ausgabe für jede Zeile der Eingabedatei erhalten. Ich brauche nur einmal Ausgabe

[30000] (03/20 00:00:02.950):{0x2D90} Pattern1 5.0.3.57 
[30000] (03/20 00:00:03.911):{0x2D90} Pattern2 5.0.3.57 
[30000] (03/20 00:00:02.950):{0x2D90} Pattern3 5.0.3.16 
[30000] (03/20 00:00:03.911):{0x2D90} Pattern4 5.0.3.16 

Hier ist das Skript:

/Pattern1/ { 
    gsub(/\./,""); 
    agtver=$5; 
} 

/Pattern2/ { 
     gsub(/\./,""); 
    ctrver=$5; 
} 

{ 
if (agtver ~ 50357 && ctrver ~ 50357) { 
     print "Blamo!"; 
} 
else print "No blamo. :(" 
} 

Und hier ist die Ausgabe, die ich bekomme:

[[email protected] Devel]$ ./fakeawk.awk < fake.txt 
No blamo. :( 
Blamo! 
Blamo! 
Blamo! 

Die Ausgabe, die ich erwartet ist eine einzige Blamo!, wenn die Muster übereinstimmen und eine einzige No blamo. :( wenn es nicht übereinstimmen.

Das Problem scheint zu sein, dass es drei separate {...} Abschnitte gibt, aber ich brauche diese, um zwei Muster verarbeiten zu können ... es sei denn, es gibt eine Möglichkeit, dies zu verdichten.

+0

Ich sehe das (plus eine ganze Menge mehr): 'Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! ' Die Logik funktioniert wie erwartet, es gibt nur viel zu viel aus. – satori7

+0

Sie sagen nicht wirklich, was genau das Skript tun soll. Es tut, was du sagst, auch wenn du das nicht gemeint hast. Vielleicht möchten Sie Agt- und Ctr-Versionen auf Null setzen, abgesehen davon, was soll das Skript eigentlich machen? Was soll die Ausgabe für diese Beispieldaten sein? – Kevin

Antwort

1

Wenn Sie Pattern1 und Pattern2 nach dem ersten Mal nie sehen, bleiben Agtver und Ctrver gesetzt. Sie müssen sie wieder auf Null setzen.

bearbeiten Debug-Ausgabe hinzugefügt, sollten Sie sehen können, wo die Logik fehlschlägt. Getestet mit Ihren Daten, danke für das Hinzufügen!

/Pattern1/ { gsub(/\./,""); agtver=$5;}  
/Pattern2/ { gsub(/\./,""); ctrver=$5;} 
{ 
    #dbg print "\n#dbg: $5=" $5 "xx\tagtver=" agtver "xx\tctrver=" ctrver "xxx\t$0=" $0 
    if (agtver ~ 50357 && ctrver ~ 50357) { 
    print "Blamo!"; 
    agtver="" ; ctrver="" 
    } 
    else print "No blamo. :(" 
} 

./fakeawk.awk < fake.txt 

Ausgang

No blamo. :(
Blamo! 
No blamo. :(
No blamo. :(

Ich hoffe, das hilft.

+0

Immer noch nicht gut. Tatsächlich hat das dazu geführt, dass die Logik nicht funktioniert, was keinen Sinn ergibt. Also hier ist der Deal. Ich analysiere eine Protokolldatei auf der Suche nach zwei Versionsnummern. Wenn diese Versionsnummern übereinstimmen, wird eine benutzerfreundliche Version wie "Version 5 Service Pack 3" gedruckt. Leider kann ich aus Gründen der Vertraulichkeit keine Angaben machen. – satori7

+0

Ich habe eine kleine Dateiprobe mit 'pattern1', pattern2, etc als Zeilen mit der 50357 an der richtigen Stelle gemacht. Kannst du das nicht auch tun? Wie bereits mehrmals wiederholt, bitte bearbeiten Sie Ihre Post, um Beispieldaten (Fälschung) und die erwartete Ausgabe einzufügen. Wenn es für das Beispiel funktioniert, sollte es funktionieren, sobald Sie alle Ihre Muster reparieren. Viel Glück. – shellter

+0

Danke. Deshalb ist die Gsub da. Es streift das "." so dass es "50357" wird. – satori7

0

TXR:

@(gather :vars (agtver ctrver)) 
@ (skip :greedy) @/Pattern1/ @{agtver /5\.0\.3\.57/} 
@ (skip :greedy) @/Pattern2/ @{ctrver /5\.0\.3\.57/} 
@(end) 
@(do (put-string "Blamo!\n")) 

Ausgang:

$ txr fake.txr fake.log 
Blamo! 

$ echo "junk" | txr fake.txr - 
false 

Die @(gather) Richtlinie für diese perfekt. Es passt Material an, das in beliebiger Reihenfolge auftreten kann, und :vars (agtver ctrver) fügt die Einschränkung hinzu, dass Bindungen für beide Variablen gefunden werden müssen oder andernfalls ein Fehler auftritt.

Wir können dann die zwei unabhängigen Bedingungen ausdrücken, nach denen wir suchen, als ein Paar von unabhängigen Übereinstimmungen mit ganzen Linien, die zwei verschiedene Variablen binden.

Die Logik kann als „bitte scannen Sie den Eingabebindungen Variablen sammeln agtver und ctrver oder sonst fail“ gelesen werden. Und dann werden die Regeln zum Sammeln der Variablen angegeben, eine pro Zeile.

Wir brauchen nicht wirklich die Nebenwirkung des Drucks Blamo!: die erfolgreiche oder fehlgeschlagene Beendigung des Programms sagt uns alles.

+0

Das ist sehr cool und sieht so aus, als würde es den Job erledigen, aber das muss mit awk gemacht werden (es ist Teil eines größeren awk-Skripts). Wenn es meine Wahl wäre, würde ich Perl benutzen, aber das bin nur ich. :( – satori7

Verwandte Themen