2017-08-22 1 views
0

J'ai un fichier qui est le journal d'un script exécuté dans un cronjob quotidien. Le fichier journal semble comme-Imprimer toutes les lignes entre deux modèles dans le shell

Aug 19 

Line1 
Line2 
Line3 
Line4 
Line5 
Line6 
Line7 
Line8 
Line9 

Aug 19 

Aug 20 

Line1 
Line2 
Line3 
Line4 
Line5 
Line6 
Line7 
Line8 
Line9 

Aug 20 

Aug 21 

Line1 
Line2 
Line3 
Line4 
Line5 
Line6 
Line7 
Line8 
Line9 

Aug 21 

Le journal est écrit par le script en commençant par la date et se terminant à la date et entre tous les journaux sont écrits.

Maintenant, quand j'essaie d'obtenir les journaux pour un seul jour en utilisant la commande ci-dessous -

sed -n '/Aug 19/,/Aug 19/p' filename 

il affiche la sortie comme -

Aug 19 

Line1 
Line2 
Line3 
Line4 
Line5 
Line6 
Line7 
Line8 
Line9 

Aug 19 

Mais si j'essaie d'obtenir les journaux de plusieurs dates, les journaux du dernier jour sont toujours manquants.

Si je Exemple- exécutez la commande

sed -n '/Aug 19/,/Aug 20/p' filename 

la sortie ressemble -

Aug 19 

Line1 
Line2 
Line3 
Line4 
Line5 
Line6 
Line7 
Line8 
Line9 

Aug 19 

Aug 20 

Je suis passé par ce site et trouvé quelques précieuses contributions à un problème similaire, mais aucune des solutions travaille pour moi. Les liens sont Link 1

Link 2

Les commandes que j'ai essayé sont -

awk '/Aug 15/{a=1}/Aug 21/{print;a=0}a' 
awk '/Aug 15/,/Aug 21/' 
sed -n '/Aug 15/,/Aug 21/p 
grep -Pzo "(?s)(Aug 15(.*?)(Aug 21|\Z))" 

mais aucune des commandes donne les journaux de la dernière date, toutes les impressions des commandes jusqu'au 1er horodatage comme J'ai montré ci-dessus.

Répondre

0

Je pense que vous pouvez utiliser la commande awk comme suit pour imprimer les lignes entre Aug 19 & Aug 20,

awk '/Aug 19/||/Aug 20/{a++}a; a==4{a=0}' file 

Brève explication,

  • /Aug 19/||/Aug 20/: trouver l'enregistrement correspondant Aug 19 ou Aug 20
  • si le critère est rempli, définissez le drapeau a++
  • si le drapeau a devant le point-virgule est supérieur à 0, cela afficherait l'enregistrement.
  • critères définitifs, si a==4, puis remis à zéro a=0, l'esprit que cela ne fonctionnait pour le cas dans l'exemple, si Aug 19 ou Aug 20 sont plus de 4, de modifier le numéro 4 dans la réponse à répondre à votre nouvelle demande.

Si vous souhaitez attribuer les motifs recherchés dans les variables, modifier la commande comme suit,

$ b="Aug 19" 
$ c="Aug 20" 
$ awk -v b="$b" -v c="$c" '$0 ~ c||$0 ~ b{a++}a; a==4{a=0}' file 
+0

@jantwisted & CWLiu Merci pour cette réponse rapide. –

+0

pourriez-vous s'il vous plaît expliquer la commande car cela résout mon problème –

+1

@CWLiu: À mon humble avis, il ne cherchera que 4 occurrences du 19 août, 20 août. Que diriez-vous s'il y a plus d'occurrences de 20 août etc, il peut ne pas les imprimer alors . – RavinderSingh13

0

Vous pouvez utiliser plusieurs motifs en les séparant par un point-virgule.

sed -n '/Aug 19/,/Aug 19/p;/Aug 20/,/Aug 20/p' filename 
+0

Cette commande donne uniquement pour les dates mentionnées. Si je veux les journaux pendant trois jours, cette commande échoue. Si je tape sed -n '/ août 19 /, 19 août/p;/21 août /, 21 août/p', alors le résultat est seulement pour le 19 août et le 21 août, mais j'ai aussi besoin du 20 août. –

+0

vous devez ajouter/Août 20 /,/Août 20/p aussi, sed -n '/ Aug 19 /,/Août 19/p;/Août 21 /,/Août 21/p;/Août 20 /,/Aug 20/p ' également – jantwisted

0

Pourriez-vous s'il vous plaît essayer la solution suivante awk trop une fois et laissez-moi savoir si cela vous aide.

awk '/Aug 19/||/Aug 20/{flag=1}; /Aug/ && (!/Aug 19/ && !/Aug 20/){flag=""} flag' Input_file 

EDIT: Ajout sortie trop ici pour laisser savoir OP.

awk '/Aug 19/||/Aug 20/{flag=1}; /Aug/ && (!/Aug 19/ && !/Aug 20/){flag=""} flag' Input_file 
Aug 19 

Line1 
Line2 
Line3 
Line4 
Line5 
Line6 
Line7 
Line8 
Line9 

Aug 19 

Aug 20 

Line1 
Line2 
Line3 
Line4 
Line5 
Line6 
Line7 
Line8 
Line9 

Aug 20 
+0

Cette commande imprime uniquement les horodatages, mais ne parvient pas à imprimer les journaux entre eux –

+0

@NishantSingh: veuillez voir mon édition maintenant où j'ai exécuté la commande et j'obtiens la sortie aussi. Faites-moi savoir si vous avez des questions sur le même. – RavinderSingh13

+0

Essayé à nouveau sur les serveurs fonctionnant sous Centos 6.9 et Ubuntu 14.04. Obtenir uniquement les horodatages en sortie. –

0

L'approche suivante est assez facile à comprendre sur le plan conceptuel ...

  • Imprimer toutes les lignes de 19 août à partir fin du fichier.
  • Inverser l'ordre des lignes (avec tac car tac est cat en arrière).
  • Imprimer toutes les lignes à partir du 21 août.
  • Inversez l'ordre des lignes dans l'ordre d'origine.

sed -ne '/Aug 19/,$p' filename | tac | sed -ne '/Aug 21/,$p' | tac 
+0

Merci, ça marche trop –