Quiero extraer todos los registros entre dos marcas de tiempo. Algunas líneas pueden no tener la marca de tiempo, pero también quiero esas líneas. En resumen, quiero cada línea que se encuentre bajo dos marcas de tiempo. Mi estructura de registro se parece 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
Supongamos que quiero extraer todo entre 2014-04-07 23:00
y 2014-04-08 02:00
.
Tenga en cuenta que es posible que la marca de tiempo de inicio o de finalización no esté en el registro, pero quiero todas las líneas entre estas dos marcas de tiempo.
Respuesta aceptada:
Puedes usar awk
por esto:
$ awk -F'[]]|[[]'
'$0 ~ /^[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^[/ && $2 >= "2014-04-08 02:00" { p=0 }
p { print $0 }' log
donde:
-F
especifica los caracteres[
y]
como separadores de campo usando una expresión regular$0
hace referencia a una línea completa$2
hace referencia al campo de fechap
se utiliza como variable booleana que protege la impresión real$0 ~ /regex/
es verdadero si la expresión regular coincide con$0
>=
se utiliza para comparar cadenas lexicográficamente (equivalente a, por ejemplo,strcmp()
)
Variaciones
La línea de comando anterior implementa la coincidencia de intervalos de tiempo abiertos a la derecha. Para obtener una semántica de intervalo cerrado, simplemente incremente su fecha correcta, por ejemplo:
$ 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
En caso de que desee hacer coincidir las marcas de tiempo en otro formato, debe modificar el $0 ~ /^[/
subexpresión. Tenga en cuenta que solía ignorar las líneas sin marcas de tiempo de la lógica de activación/desactivación de impresión.
Por ejemplo, para un formato de marca de tiempo como YYYY-MM-DD HH24:MI:SS
(sin []
llaves) podría modificar el comando de esta manera:
$ 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
(tenga en cuenta que también se cambia el separador de campo:transición en blanco/no en blanco, el valor predeterminado)