Ho un file di registro da 8 GB (registro di produzione Rails). Devo tagliarlo tra alcune date (righe). Quale comando posso usare per fare questo?
sed
lo farà facilmente.
Ho un file di registro da 8 GB (registro di produzione Rails). Devo tagliarlo tra alcune date (righe). Quale comando posso usare per fare questo?
sed
lo farà facilmente.
Risposte:
Qualcosa di simile a
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
ti permette di vedere sullo schermo cosa viene messo in archivio cut-log
.
MODIFICARE:
Per soddisfare i rigorosi standard di fred.bear, ecco una soluzione sed (anche se probabilmente la soluzione awk è molto più carina):
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
può corrispondere awk
per la velocità, ed è stato in realtà un po 'più veloce.
Per stampare tutto tra FOO e BAR compreso, provare:
$ sed -n '/FOO/,/BAR/p' file.txt
Questo farà ciò che vuoi ...
Vengono visualizzate sia le date dei parametri Inclusa che Esclusa.
# 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"
Verifica una data (ordinata) nel campo 2 ... Ecco un esempio dei dati del test
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
Ed ecco il generatore di dati di test .
awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
if
istruzione aggiuntiva in totale (nemmeno 1 per riga). il flusso logico è effettivamente lo stesso e la differenza nel tempo di esecuzione verrebbe contata in nanosecondi .... L'unica ragione per cui non ho usato "altro" è che questo è effettivamente il mio primo awk
script in assoluto (a parte un giorno 4 anni fa quando ho suonato con alcuni esempi) ... e questo è il primo meccanismo di diramazione praticabile che ho trovato ... (e come detto. è altrettanto veloce) .. Generalmente uso sed
Tryq
Se nel tuo file di registro hai le date in questo formato YYYY-MM-DD
, quindi, per trovare tutte le voci per dire, 2011-02-10, puoi fare:
grep 2011-02-10 log_file
Ora, diciamo, se si desidera trovare le voci per il 2011-02-10 e il 2011-02-11, utilizzare nuovamente grep
ma con più schemi:
grep -E '2011-02-10|2011-02-11' log_file
grep
cercherà l'intero file, anche se l' intervallo di date è all'inizio del file. In media questo raddoppia il tempo di una ricerca, rispetto a "exit-after-last-item-in-range" ... Mi sto solo preoccupando di menzionarlo a causa delle dimensioni del file da 8 GB menzionate nella domanda, Your i risultati del tempo grep sono quasi identici all'esempio sed qui (1 minuto e 58 secondi). Ecco il link ai risultati dei miei test cronometrati
Lavorare con questa dimensione di file è sempre difficile.
Un modo per andare avanti potrebbe essere quello di dividere questo file in un paio di piccoli, per fare ciò è possibile usare il comando split.
split -d -l 50000 ToBigFile.data file_
Anche se è diviso puoi sempre lavorare con il file come se fosse uno usando un bash per il ciclo
for f in `ls file_*`; do cat $f; done;
Ma invece del gatto puoi usare grep invertito per sbarazzarti di dati indesiderati, questo è irrilevante per questo. (o il tipo di raffinatezza di cui hai bisogno).
A questo punto lavorerai solo con molti file più piccoli, e i comandi che gli altri menzionati sopra lavoreranno su molti file più piccoli.
E quando hai finito, puoi usare un secondo ciclo per creare nuovamente il nuovo file più piccolo.
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
Aggiornamento Dal momento che iniziamo a dividere i dati in più file, ci sarà molto lavoro con l'hard disk e ci vorrà del tempo. (In questa domanda apparentemente 5min).
D'altra parte i passi successivi sarebbero probabilmente più veloci.
Quindi questo metodo è probabilmente inutile per semplici operazioni grep, awk, sed, ma se i modelli di ricerca diventano più complicati, potrebbero diventare più veloci.
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file