2012-03-26 7 views
1

Also ich versuche, eine ziemlich langweilige Datenerfassung aus Hunderten von verschiedenen Protokolldateien zu automatisieren. Das folgende Skript:Tweaking awk zum Drucken verschiedener Dinge, wenn ein regulärer Ausdruck passt oder nicht

awk '/Loop/ { printf $4, }' log*weak*"$factor"x

wird für die Linie suchen, die „Loop Zeit von $ Zeit“, sagen und drucken Sie die Zeit

Der Fall, den ich mit jetzt bin versucht, obwohl zu beschäftigen, ist, wenn es waren Laufzeitfehler und das Protokoll wurde nie geschrieben. Das heißt, die Protokolldatei ist vorhanden, enthält jedoch keinen Text. Das Problem ist, dass das obige Skript nur das Protokoll überspringen wird. Ich möchte, dass es ein Leerzeichen ausgibt (um die aus diesem Grund erstellte CSV einfacher auszurichten).

Also gibt es eine Möglichkeit, $ 4 (die Zeit) zu drucken, wenn/Loop/übereinstimmt, aber "," wenn nicht?

+0

Ihre Dateien enthalten also höchstens eine Zeile, die mit "Loop" übereinstimmt? – Mat

+0

Ja, das Programm verwendet eine Vorlage, die nur einmal "Loop" hat. Es kann kein Problem feststellen und gibt die Zeit aus dieser Zeile aus. Wenn jedoch "Loop" nicht vorhanden ist, wird nichts ausgegeben. Ich möchte, dass etwas ausgedruckt wird, damit ich auf dem CSV sehen kann, dass dieser Test erneut ausgeführt werden muss. – user1209326

Antwort

3

Keine Notwendigkeit der found Variable:

awk ' 
    /Loop/ { 
    print $4 
    } 

    END { 
    if (! $0) { 
     print " " 
    } 
    } 
' YOURINPUTS 

Nach der Lektüre Ihrer Kommentare Dieses einfache Schnipsel sollte es tun:

awk '{print ($4) ? $4 : " "}' FILE.CSV 

Es ist ein ternärer Operator wie in C.

+0

Vielen Dank für Ihre Antwort - Ich mag es besser, sich nicht auf die Variable verlassen zu müssen. Nur so verstehe ich awk etwas besser, was gibt das 'END' Schlüsselwort an? Ist das das Ende der Regexp oder der letzte Block des Skripts? – user1209326

+0

@ user1209326, wird der END-Block nach der Verarbeitung aller Dateien in der Befehlszeile ausgeführt. Ein bisschen weniger obskur ist 'END {if (NR == 0) print" "}' zu überprüfen, dass die Zeilennummer Null ist, wenn die Datei leer ist. –

+0

@Glennjackman Ohh ich verstehe. Ich denke, ich war mit meiner Frage nicht klar genug. Ich mache eine Tabellenkalkulation, jedes Mal wenn ich eine eigene Zelle habe. Das Problem ist, dass das Skript, wenn die Protokolldatei leer ist, keine leere Zelle erstellt und jede nachfolgende Zelle nicht ordnungsgemäß mit ihrer Spalte ausgerichtet ist. Also das Verhalten, das ich hier herausholen will, ist eine Nummer, wenn die Protokolldatei eine Nummer hat, und ein Leerzeichen sonst. Also würde die CSV wie "1.123,, 2.134" aussehen. Ich würde annehmen, dass ich etwas implementieren müsste, das läuft, während die Dateien verarbeitet werden, nein? – user1209326

2

Was dazu:

awk ' 
    FILENAME != oldf { oldf = FILENAME ; If (found != 0) { prínt " " } ; 
        found = 0 } 
    /Loop/ { 
    print $4, ; 
    found++ 
    } 

    END { 
    if (! found) { 
     print " " 
    } 
    } 
' YOURINPUTS 
+0

Ich habe das umformatiert, nur um das Lesen ohne das seitliche Scrollen zu erleichtern. Ansonsten, ja, genau das habe ich mir gedacht. – larsks

+0

Wie Sie sehen können, bin ich mit awk nicht sehr vertraut. Wenn ich diese Zeile verwende, zum Beispiel 500 Protokolldateien, wird 'find' jedes Mal auf 0 reinitialisiert? Ich habe das noch nicht auf dem Computer mit den Dateien ausgeführt, aber wird eine Instanz von "Loop" jede nachfolgende "if (! Found)" Bedingung abwerfen? – user1209326

+0

@ user1209326, awk Variablen sind global, so 'gefunden' wird nicht reinitialisieren. –

Verwandte Themen