2017-01-05 1 views
0

Ich habe eine Protokolldatei und ich möchte das Ergebnis von einem Grep teilen und durch einen anderen Grep zählen und zählen.Teilen Sie das Ergebnis von zwei Grep und Wortzählung

Es ist hässlich, funktioniert nicht und ich kann es wahrscheinlich auf eine bessere Weise tun, aber ich weiß nicht wie.

Auch ich würde gerne wissen, ob es möglich ID inkrementell auf einen Protokollstrom, der zum Beispiel Schwanz gelesen wird.

+1

Welche Ausgabe erwarten Sie? Bash/sh kann Fließkomma-Arithmetik nicht direkt ausführen. Ich würde nach einer Skriptsprache (Perl/Ruby/Python) greifen. – choroba

+0

Mögliches Duplikat von [Dividiere zwei Variablen in bash] (http://stackoverflow.com/questions/30398014/divide-two-variables-in-bash) – VM17

+0

Du bist dem Zeichen '|' nicht genug entgangen. Sie haben es nur gematcht, um zu vermeiden, dass die Shell es als Teil einer Pipeline behandelt, aber "grep" behandelt es immer noch als Literalzeichen und nicht als Änderungsoperator, es sei denn, es wird wieder * escaped *. Entweder 'grep timed \\\ | \\\ | error \\\ | Error' oder (einfacher)' grep 'timed \ | error \ | Error'' oder (am einfachsten von allen) 'grep -E' zeitgesteuert | error | Error'' (erweiterte reguläre Ausdrücke * behandeln * unescaped '|' als Änderungsoperator). – chepner

Antwort

2

Zunächst einmal sollten Sie wissen, dass sowohl grep|wc -l wird Anzahl der gefundenen Zeilen zählen statt Vorkommen, ich hoffe, das ist, was Sie wirklich wollen.

In Bezug auf Ihre Anforderung, in der Tat ist Ihr Ansatz hässlich (7 Prozesse), abgesehen von den Fehlern. Der Auftrag kann durch eine einzige awk Zeile:

awk '/timed|[Ee]rror/{a++}/Duration/{b++}END{printf "%.2f\n",a/b}' log2.txt 

Die obige Linie das Ergebnis berechnet, basierend auf abgestimmte Anzahl von Linien, gleiche wie Ihr grep|wc -l.

+0

Ich brauchte genau "Anzahl der übereinstimmenden Linien", die perfekt ist. Was {a ++} bedeutet? Danke vielmals ! – Mio

+1

@BeniMio Wenn Sie C oder C++ kennen, wissen Sie a ++. es ist dasselbe wie 'a + = 1' – Kent

1

Sie haben mehrere Probleme:

  1. Sie versuchen, Shell-Befehle direkt in einem arithmetischen Ausdruck laufen.
  2. Sie übergeben den korrekten regulären Ausdruck nicht an grep.
  3. Sie müssen sicherstellen, dass mindestens einer der Operanden ein Fließkommawert ist, um die Fließkomma-Division von zsh auszulösen.

Jede Pipeline kann auch auf einen einzigen Befehl reduziert werden; Verwenden Sie die Eingabeumleitung anstelle von cat, und verwenden Sie die Option -c, um die Anzahl der Zeilen zu ermitteln, die dem regulären Ausdruck entsprechen.

echo $((1.0 * $(grep -c 'timed\|error\|Error' log2.txt)/$(grep -c Duration log2.txt)) 

Grund reguläre Ausdrücke behandeln unescaped | als Literalzeichen, nicht eine Änderung Operator.

$ echo foo | grep foo\|bar 
$ echo foo | grep foo\\\|bar # Pass a literal backslash as part of the regex 
foo 
$ echo foo | grep 'foo\|bar' # Use '...' instead of explicitly escaping \ and | 
foo 
$ echo foo | grep -E 'foo|bar' # Use extended regular expressions instead 
+0

Vielen Dank für diese zusätzlichen Erklärungen. – Mio

Verwandte Themen