Voglio estrarre tutti i registri tra due timestamp. Alcune righe potrebbero non avere il timestamp, ma voglio anche quelle righe. In breve, voglio ogni riga che cade sotto due timestamp. La mia struttura del registro è simile a:
[2014-04-07 23:59:58] CheckForCallAction [ERROR] Exception caught in +CheckForCallAction :: null
--Checking user--
Post
[2014-04-08 00:00:03] MobileAppRequestFilter [DEBUG] Action requested checkforcall
Supponiamo che io voglia estrarre tutto tra 2014-04-07 23:00
e 2014-04-08 02:00
.
Tieni presente che il timestamp di inizio o di fine potrebbe non essere presente nel registro, ma voglio ogni riga tra questi due timestamp.
Risposta accettata:
Puoi usare awk
per questo:
$ awk -F'[]]|[[]'
'$0 ~ /^[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^[/ && $2 >= "2014-04-08 02:00" { p=0 }
p { print $0 }' log
Dove:
-F
specifica i caratteri[
e]
come separatori di campo usando un'espressione regolare$0
fa riferimento a una riga completa$2
fa riferimento al campo della datap
viene utilizzata come variabile booleana che protegge la stampa effettiva$0 ~ /regex/
è vero se regex corrisponde a$0
>=
viene utilizzato per confrontare lessicograficamente una stringa (equivalente ad es.strcmp()
)
Varianti
La riga di comando precedente implementa la corrispondenza dell'intervallo di tempo con apertura a destra. Per ottenere la semantica a intervalli chiusi, basta aumentare la data corretta, ad esempio:
$ awk -F'[]]|[[]'
'$0 ~ /^[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^[/ && $2 >= "2014-04-08 02:00:01" { p=0 }
p { print $0 }' log
Nel caso in cui desideri abbinare i timestamp in un altro formato, devi modificare il $0 ~ /^[/
sottoespressione. Nota che ignorava le righe senza alcun timestamp dalla logica di attivazione/disattivazione della stampa.
Ad esempio per un formato timestamp come YYYY-MM-DD HH24:MI:SS
(senza []
parentesi graffe) potresti modificare il comando in questo modo:
$ awk
'$0 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9]/
{
if ($1" "$2 >= "2014-04-07 23:00") p=1;
if ($1" "$2 >= "2014-04-08 02:00:01") p=0;
}
p { print $0 }' log
(notare che anche il separatore di campo è cambiato – in transizione vuota/non vuota, l'impostazione predefinita)