Je veux extraire tous les journaux entre deux horodatages. Certaines lignes peuvent ne pas avoir l'horodatage, mais je veux aussi ces lignes. En bref, je veux que chaque ligne tombe sous deux horodatages. Ma structure de journal ressemble à :
[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
Supposons que je veuille tout extraire entre 2014-04-07 23:00
et 2014-04-08 02:00
.
Veuillez noter que l'horodatage de début ou l'horodatage de fin ne figure peut-être pas dans le journal, mais je veux chaque ligne entre ces deux horodatages.
Réponse acceptée :
Vous pouvez utiliser awk
pour cela :
$ awk -F'[]]|[[]'
'$0 ~ /^[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^[/ && $2 >= "2014-04-08 02:00" { p=0 }
p { print $0 }' log
Où :
-F
spécifie les caractères[
et]
comme séparateurs de champs à l'aide d'une expression régulière$0
fait référence à une ligne complète$2
fait référence au champ de datep
est utilisé comme variable booléenne qui protège l'impression réelle$0 ~ /regex/
est vrai si regex correspond à$0
>=
est utilisé pour comparer lexicographiquement une chaîne (équivalent à, par exemple,strcmp()
)
Variantes
La ligne de commande ci-dessus implémente la correspondance d'intervalle de temps d'ouverture à droite. Pour obtenir une sémantique d'intervalle fermé, il suffit d'incrémenter votre bonne date, par exemple :
$ 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
Si vous souhaitez faire correspondre les horodatages dans un autre format, vous devez modifier le $0 ~ /^[/
sous-expression. Notez qu'il ignorait les lignes sans horodatage de la logique d'activation/désactivation de l'impression.
Par exemple pour un format d'horodatage comme YYYY-MM-DD HH24:MI:SS
(sans []
accolades) vous pouvez modifier la commande comme ceci :
$ 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
(notez que le séparateur de champs est également modifié - transition vide/non vide, la valeur par défaut)