2017-02-23 1 views
0

Ich möchte Zeilen mit Zeitstempeln in einer Protokolldatei suchen (nicht alle Zeilen haben Zeitstempel) und ich möchte diese Zeitstempel auch behalten, damit ich die Zeitspanne sehen kann, die aktive Tag Nummer usw.grep passte Zeilen zu einer Datei und entsprach Strings zu einer anderen Datei

201 3083560 2013-10-21T13:57:55.334+0200 time|bootup 
202 3083560 2013-10-21T13:57:55.334+0200 startup 
204 3083579 2013-10-21T13:57:55.353+0200 system|device 
205 3083579 2013-10-21T13:57:55.353+0200 system|manufacturer 
206 3083579 2013-10-21T13:57:55.353+0200 system|model 

ich die Befehle ausführen kann:

grep -P '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\t' usr.log > file1.txt 
grep -Po '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\t' usr.log > file2.txt 

Und meine Frage ist, kann ich grep nur einmal ausgeführt zu bekommen, was ich mit einigen Rohren? Das Muster bleibt gleich, also denke ich, dass grep mich einmal etwas retten könnte, da ich 30k individuelle Benutzerprotokolldateien habe.

* Es ist nützlich, die Registerkarte am Ende des Musters zu behalten, weil in einigen Zeilen Zeitwerte in der letzten Spalte sind, so dass ich \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\n ausschließen muss.

* Meine Umgebung ist CentOS 7, grep (GNU) 2.20.

Vielen Dank!

+0

Sie haben es nicht zweimal laufen, können Sie 'grep -oP' in der' usr.log' direkt. – Inian

+0

Auch Ihre Regex '\ d {4} - \ d {2} - \ d {2} T \ d {2}: \ d {2} \ d {2} \. \ D {3} [+ -] \ d {4} \ t' oder '\ d {4} - \ d {2} - \ d {2} T \ d {2}: \ d {2} \ d {2}. \ d {3} [+ -] \ d {4} \ n' stimmt nicht mit den Zeilen in der Beispieleingabedatei überein – Inian

+0

Vielen Dank! Ich habe vergessen, ein Extra hinzuzufügen: in das Muster. Jetzt habe ich es behoben. Aber wie kann es in einem Lauf gemacht werden? Ich möchte auch Datei1.txt behalten. – leoce

Antwort

0

Ich glaube nicht, dass dies durch eine grep getan werden kann, aber man kann mit dem Lesen Sie die Datei einmal weg und grep ‚s Ausgang Wiederverwendung, wenn Sie die Ausgabe eines grep zum anderen senden:

regex='\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}\t' 
grep -P "$regex" usr.log | tee file1.txt | grep -Po "$regex" > file2.txt 

tee file speichert die Eingabe in die Datei und druckt ebenfalls auf stdout, wodurch es sinnvoll ist, die Ausgabe in der Mitte einer Pipe zu speichern.

Wenn Sie awk verwenden können, nehmen Sie können dann nutzen sie das dritte Feld ist, und tun es in einem Lauf:

awk '/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}.[0-9]{4}\t/ \ 
    {print $3 > "file2.txt"; print}' usr.log > file1.txt 
0

Wenn Sie Ihre Regex in Perl laufen Sie Ihre Ausgabe zwischen stdout aufspalten und stderr die $& Variable nur die gefundenen String drucken:

perl -ne 'if(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}[+-]\d{4}/){print; print STDERR "$&\n"}' usr.log > file1.txt 2> file2.txt 
Verwandte Themen