Filtrage sur les dates avec grep et awk

J'ai créé l'alias ci-dessous dans mon file .bash_aliases

 alias auth="grep \"$(date|awk '{print $2,$3}')\" /var/log/auth.log | grep -E '(BREAK-IN|Invalid user|Failed|refused|su|Illegal)'" 

Ceci est censé:

  • vérifier la date d'aujourd'hui
  • grep auth.log pour les messages d'aujourd'hui
  • grep messages d'aujourd'hui pour les messages d'avertissement correspondant à des strings particulières

Cependant, cela ne fonctionne que s'il y a un jour à 2 numbers car les jours numérotés <10 n'ont pas de zéro précédent.

Par exemple, j'exécute la date et dirige le résultat vers awk . date sorties Sat Jan 1 04:56:10 GMT 2011 et ensuite awk capture $2 $3 et $3 et les nourrit dans grep comme suit

 Jan 1 

Cependant, lorsqu'il y a un jour à un seul chiffre, les messages dans auth.log apparaissent comme suit

 Jan 1 00:44:57 linux su[21249]: pam_unix(su:session): session closed for user root 

Il y a donc deux espaces suivant Jan dans le auth.log mais un seul espace suit Jan dans ma command grep

Comment puis-je modifier la command pour autoriser l'espace supplémentaire?

Plutôt que d'utiliser la date | awk ... date | awk ... , vous pouvez utiliser un spécificateur de format avec la command de date pour le format que vous voulez. Selon la page de manuel date(1) , %b est le nom abrégé du mois et %e est le jour du mois, espace rempli, identique à %_d .

La command de date suivante devrait vous donner une string dans la forme que vous voulez:

 date "+%b %e" 

Vous pouvez également mettre d'autres caractères dans le spécificateur de format, donc si vous utilisez:

 date "+^%b %e" 

vous obtiendrez un motif grep qui correspond à la date uniquement au début de la ligne. Cela empêcherait toute correspondance fausse où il y a une date dans la partie message du journal.

Comme le souligne Steven D, vous pouvez également le faire avec une seule invocation de grep :

 auth() { grep -E "$(date '+^%b %e')"'.*(BREAK-IN|Invalid|user|Failed|refused|su|Illegal)' /var/log/auth.log } 

J'ai apporté quelques modifications en fonction des problèmes mentionnés dans les commentaires relatifs aux citations. Mes règles de citation sont d'utiliser des guillemets simples pour regrouper des mots distincts en un seul mot et pour protéger contre l'expansion des métacaractères et d'utiliser des guillemets doubles uniquement lorsque vous souhaitez développer une string de plusieurs mots.

La réponse originale avait la string de format de date entre guillemets, ce qui était faux selon mes règles ci-dessus. J'ai maintenant changé ça. Une modification place la string grep entre guillemets doubles. Je l'ai mis en guillemets car il y a souvent un chevauchement entre les métacaractères du shell et les méta-caractères d'expression régulière (RE) de grep que vous voulez presque toujours citer en une seule fois les RE en grep. La string actuelle peut ne pas avoir besoin de guillemets simples, mais si cette fonction de shell évolue avec le time, elle peut rompre avec les changements futurs.

Parce que la question se posait à propos d'une command pour placer un alias, il y avait un niveau supplémentaire de citation qui n'était pas montré dans cette réponse. Il serait plus simple d'utiliser une fonction shell au lieu d'un alias pour ne pas avoir à gérer ce niveau supplémentaire de citation. Citation nestede peut get désordonné rapidement, donc tout ce que vous pouvez faire pour l'éviter, vous devriez faire.

J'ai testé cela comme une fonction de shell, en utilisant la suggestion de Gilles pour la datation et cela "fonctionne pour moi".