Ich habe eine 8-GB-Protokolldatei (Rails-Produktionsprotokoll). Ich muss es zwischen einigen Daten (Linien) schneiden. Welchen Befehl könnte ich verwenden, um dies zu tun?
sed
machst du es leicht.
Ich habe eine 8-GB-Protokolldatei (Rails-Produktionsprotokoll). Ich muss es zwischen einigen Daten (Linien) schneiden. Welchen Befehl könnte ich verwenden, um dies zu tun?
sed
machst du es leicht.
Antworten:
So etwas wie
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
Damit können Sie auf dem Bildschirm sehen, was in der Datei abgelegt wird cut-log
.
BEARBEITEN:
Um den hohen Ansprüchen von fred.bear gerecht zu werden, hier eine sed-Lösung (obwohl die awk-Lösung wahrscheinlich viel hübscher ist):
b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"
sed
kann awk
für die Geschwindigkeit passen , und es war tatsächlich ein bisschen schneller.
Um alles zwischen FOO und BAR einschließlich zu drucken, versuchen Sie:
$ sed -n '/FOO/,/BAR/p' file.txt
Dies wird tun, was Sie wollen ...
Sowohl einschließlich als auch ausschließlich der Parameterdaten werden angezeigt.
# set Test args
set 2011-02-24 2011-02-26 "junk"
from="$1"
till="$2"
file="$3"
# EITHER ==== +++++++++
# Ouptut lines between two parameter dates INCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 >= from) && ($2 <= till) { print $0 ; next }
($2 > till) { exit }' "$file"
# OR ======== ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 > from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
Es wird in Feld 2 nach einem (sortierten) Datum gesucht ... Hier ein Beispiel für die Testdaten
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
Und hier ist der Testdatengenerator .
awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
if
Aussage insgesamt (nicht einmal 1 pro Zeile) , dh. Der logische Ablauf ist praktisch derselbe und die Laufzeitdifferenz wird in Nanosekunden gezählt. Der einzige Grund, warum ich kein "else" verwendet habe, ist, dass dies praktisch mein erstes awk
Skript ist (abgesehen von einem Tag und vier Jahren) Vor, als ich mit einigen Beispielen gespielt habe) ... und das ist der erste funktionsfähige Verzweigungsmechanismus, den ich gefunden habe ... (und wie erwähnt. Es ist genauso schnell) .. Ich verwende generell sed
Tryq
Wenn Sie in Ihrer Protokolldatei die Daten in diesem Format haben YYYY-MM-DD
, können Sie Folgendes tun, um alle Einträge beispielsweise vom 10.02.2011 zu finden:
grep 2011-02-10 log_file
Sagen wir nun, wenn Sie die Einträge für 2011-02-10 und 2011-02-11 finden möchten, dann verwenden Sie erneut, grep
aber mit mehreren Mustern:
grep -E '2011-02-10|2011-02-11' log_file
grep
die gesamte Datei suchen, auch wenn das Datum Bereich am Anfang der Datei ist. Im Durchschnitt verdoppelt sich die Zeit für eine Suche im Vergleich zu "Exit-after-last-item-in-range" Die Grep-Zeit-Ergebnisse sind fast identisch mit dem hier gezeigten Sed-Beispiel (1 Min. 58 Sek.). Hier ist der Link zu meinen Zeittestergebnissen
Das Arbeiten mit dieser Dateigröße ist immer schwierig.
Sie können diese Datei auch in ein paar kleine Dateien aufteilen. Verwenden Sie hierzu den Befehl split.
split -d -l 50000 ToBigFile.data file_
Auch wenn es aufgeteilt ist, können Sie mit der Datei arbeiten, als ob Sie eine Bash for-Schleife verwenden würden
for f in `ls file_*`; do cat $f; done;
Anstelle der Katze können Sie jedoch auch invertiertes grep verwenden, um unerwünschte Daten zu entfernen, was für diesen Zweck irrelevant ist. (oder die Art der Verfeinerung, die Sie benötigen).
An diesem Punkt arbeiten Sie nur mit vielen kleineren Dateien, und die Befehle, die oben erwähnt wurden, funktionieren bei vielen kleineren Dateien reibungsloser.
Und wenn Sie fertig sind, können Sie eine zweite for-Schleife verwenden, um die neue kleinere Datei erneut zu erstellen.
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
Update Da wir anfangen, die Daten in mehrere Dateien aufzuteilen, wird es eine Menge Arbeit mit der Festplatte geben, und das braucht Zeit. (In dieser Frage offenbar 5min).
Andererseits wären die nächsten Schritte wahrscheinlich schneller.
Daher ist diese Methode für einfache grep-, awk- und sed-Operationen wahrscheinlich sinnlos, aber wenn die Suchmuster komplizierter werden, kann sie schneller werden.
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file