Quiero extraer todos los registros entre dos marcas de tiempo. Es posible que algunas líneas no tengan la marca de tiempo, pero también quiero esas líneas. En resumen, quiero cada línea que se clasifique en dos marcas de tiempo. Mi estructura de registro se ve así:
[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 la marca de hora de inicio o la marca de hora de finalización pueden no estar allí en el registro, pero quiero que cada línea entre estas dos marcas de tiempo.
text-processing
sed
awk
grep
Amit
fuente
fuente
date -d
comando y usándola para construir el patrón de búsqueda.Respuestas:
Puedes usar
awk
para esto:Dónde:
-F
especifica los caracteres[
y]
como separadores de campo utilizando 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 cierto si la expresión regular coincide$0
>=
se usa para comparar cadenas lexicográficamente (equivalente a, por ejemplostrcmp()
)Variaciones
La línea de comando anterior implementa la coincidencia de intervalo de tiempo de apertura a la derecha . Para obtener una semántica de intervalo cerrado, simplemente incremente su fecha correcta, por ejemplo:
En caso de que desee hacer coincidir las marcas de tiempo en otro formato, debe modificar la
$0 ~ /^\[/
expresión secundaria. Tenga en cuenta que solía ignorar líneas sin ninguna marca de tiempo de la lógica de encendido / apagado de impresión.Por ejemplo, para un formato de marca de tiempo como
YYYY-MM-DD HH24:MI:SS
(sin[]
llaves), puede modificar el comando de esta manera:(tenga en cuenta que también se cambia el separador de campo - a transición en blanco / no en blanco, el valor predeterminado)
fuente
$1 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ && $2 ~/[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/ { Time = $1" "$2; if (Time >= "2014-04-07 23:00" ) { p=1 } if (Time >= "2014-04-08 02:00:01" ) { p=0 } } p
code
$ 0 ~ / ^ [az | AZ] {4} - [0-9] {2} - [0-9] {4} [0-2] [0-9 ]: [0-5] [0-9]: [0-5] [0-9] / && $ 1 "" $ 2> = "Abr-07-2014 11:00" {p = 1} $ 0 ~ / ^ [az | AZ] {4} - [0-9] {2} - [0-9] {4} [0-2] [0-9]: [0-5] [0-9]: [0 -5] [0-9] / && $ 1 "" $ 2> = "Abr-07-2014 12:00:01" {p = 0}code
pero no funcionaEcha un vistazo
dategrep
en https://github.com/mdom/dategrepDescripción:
Ejemplos de uso:
Aunque esta limitación puede hacer que esto no sea adecuado para su pregunta exacta:
fuente
Una alternativa
awk
o una herramienta no estándar es usar GNUgrep
para sus greps contextuales. GNUgrep
le permitirá especificar el número de líneas después de una coincidencia positiva para imprimir-A
y las líneas anteriores para imprimir.-B
Por ejemplo:Lo anterior básicamente le dice
grep
que imprima las 10,000 líneas que siguen a la línea que coincide con el patrón en el que desea comenzar, haciendo que su salida comience efectivamente donde lo desea e ir hasta el final (con suerte) mientras que el segundoegrep
en el pipeline le dice que solo imprima la línea con el delimitador final y las 10,000 líneas anteriores. El resultado final de estos dos es comenzar donde quieres y no pasar donde le dijiste que se detuviera.10,000 es solo un número que se me ocurrió, no dude en cambiarlo a un millón si cree que su producción será demasiado larga.
fuente
sed
que también está en busca de coincidencias literales.dategrep
es probablemente la respuesta más correcta de todas las que se dan (ya que necesita poder "confundirse" con las marcas de tiempo que aceptará), pero como dice la respuesta, solo lo mencioné como una alternativa. Dicho esto, si el registro está lo suficientemente activo como para generar suficiente salida para garantizar el corte, probablemente también tenga algún tipo de entrada para el período de tiempo dado.Usando sed:
Copia esto en un archivo. Si no desea ver información de depuración, la depuración se envía a stderr, así que simplemente agregue "2> / dev / null"
fuente