Je veux extraire tous les journaux entre deux horodatages. Certaines lignes peuvent ne pas avoir d'horodatage, mais je veux aussi ces lignes. En bref, je veux que chaque ligne tombe sous deux horodatages. Ma structure de journal ressemble à ceci:
[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 extraire tout 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 peuvent ne pas être présents dans le journal, mais je veux que chaque ligne entre ces deux horodatages.
text-processing
sed
awk
grep
Amit
la source
la source
date -d
commande et en l'utilisant pour construire le modèle de recherche.Réponses:
Vous pouvez utiliser
awk
pour cela:Où:
-F
spécifie les caractères[
et]
comme séparateurs de champ à l'aide d'une expression régulière$0
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 exemplestrcmp()
)Variations
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:
Si vous souhaitez faire correspondre des horodatages dans un autre format, vous devez modifier la
$0 ~ /^\[/
sous-expression. Notez qu'il ignorait les lignes sans horodatage de la logique d'impression activée / désactivée.Par exemple, pour un format d'horodatage comme
YYYY-MM-DD HH24:MI:SS
(sans[]
accolades), vous pouvez modifier la commande comme ceci:(notez que le séparateur de champs est également modifié - en transition vide / non vide, la valeur par défaut)
la source
$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> = "Apr-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> = "Apr-07-2014 12:00:01" {p = 0}code
mais cela ne fonctionne pasDécouvrez
dategrep
à https://github.com/mdom/dategrepLa description:
Exemples d'utilisation:
Bien que cette limitation puisse rendre cela inapproprié pour votre question exacte:
la source
Une alternative
awk
ou un outil non standard consiste à utiliser GNUgrep
pour ses greps contextuels. GNUgrep
vous permettra de spécifier le nombre de lignes après une correspondance positive avec laquelle imprimer-A
et les lignes précédentes avec lesquelles imprimer-B
Par exemple:Ce qui précède indique essentiellement
grep
d'imprimer les 10 000 lignes qui suivent la ligne qui correspond au modèle auquel vous souhaitez commencer, ce qui fait que votre sortie commence là où vous le souhaitez et va jusqu'à la fin (avec un peu de chance) tandis que la secondeegrep
dans le pipeline lui indique de n'imprimer que la ligne avec le délimiteur de fin et les 10 000 lignes devant elle. Le résultat final de ces deux est de commencer où vous voulez et de ne pas aller là où vous lui avez dit d'arrêter.10000 est juste un nombre que j'ai trouvé, n'hésitez pas à le changer en un million si vous pensez que votre sortie va être trop longue.
la source
sed
qui recherche également des correspondances littérales.dategrep
est probablement la réponse la plus correcte de toutes celles données (car vous devez être en mesure de vous rendre "flou" sur les horodatages que vous accepterez) mais comme la réponse le dit, je le mentionnais simplement comme une alternative. Cela dit, si le journal est suffisamment actif pour générer suffisamment de sortie pour justifier la coupe, il y aura probablement aussi une sorte d'entrée pour la période donnée.Utilisation de sed:
Copiez ceci dans un fichier. Si vous ne voulez pas voir les informations de débogage, le débogage est envoyé à stderr alors ajoutez simplement "2> / dev / null"
la source