Question

Je suis en train d'écrire un simple script .sh pour analyser un fichier journal Exim pour les chaînes correspondant à " o '" ;. Actuellement, lors de l’affichage du fichier output.txt, il n’ya que 0 imprimé sur chaque ligne (606 lignes). Je suppose que ma logique est fausse, car awk ne renvoie aucune erreur.

Voici mon code (mis à jour pour les problèmes de concaténation et de compteur). Edit: J'ai adopté un nouveau code issu de la réponse de dmckee avec laquelle je travaille maintenant sur l'ancien code en faveur de la simplicité.

awk '/o'\''/ {
         line = "> ";
         for(i = 20; i <= 33; i++) {
           line = line " " $i;
         }
         print line;
    }' /var/log/exim/main.log > output.txt

Des idées?

EDIT: Par souci de clarté, je cherche "& o;" dans les adresses e-mail, car 'est un caractère illégal dans les adresses e-mail (et dans nos bases de données, apparaît uniquement avec des noms avec un préfixe «o»).

EDIT 2: conformément à la demande de commentaire, voici un exemple précis de la sortie souhaitée:

[xxx.xxx.xxx.xxx] kathleen.o'toole@domain.com <kathleen.o'toole@domain.com> routing defer (-51): retry time not reached

[xxx.xxx.xxx.xxx] julie.o'brien@domain.com <julie.o'brien@domain.com> routing defer (-51): retry time not reached

[xxx.xxx.xxx.xxx] james.o'dell@domain.com <james.o'dell@domain.com> routing defer (-51): retry time not reached

[xxx.xxx.xxx.xxx] daniel_o'leary@domain.com <aniel_o'leary@domain.com> routing defer (-51): retry time not reached

La raison pour laquelle je commence à 20 dans ma boucle est parce que tout ce qui précède le 20e champ ne sont que des informations de journal standard qui ne sont pas nécessaires à mes fins ici. Tout ce dont j'ai besoin, c'est de l'adresse IP et au-delà pour cette solution (les messages pour chaque erreur 550 sont différents pour chaque serveur de messagerie utilisé. Je suis en train de compiler une liste des plus courants)

Était-ce utile?

La solution

Le grep n’est pas vraiment nécessaire ici. Laissez awk sélectionner les lignes qui vous conviennent (et corrigez le bogue de concaténation comme décrit dans les notices & # 932; & # 937; & # 932; & # 918; & # 921; & # 927; & # 933;):

awk '/o'\''/ {
             line = "> ";
             for(i = 20; i <= 33; i++) {
               line = line " " $i;
             }
             print line;
        }' /var/log/exim/main.log > output.txt

Bien sûr, vous finirez par avoir besoin de s'échapper bizarrement si vous le faites au balai, comme ci-dessus. C'est plus propre dans un script ...

Modifier: lors du premier passage, j'ai raté le problème + = ...

Supposons également que la ligne que vous avez indiquée ci-dessus est partielle, car elle ne comporte que 13 champs (les champs sont par défaut délimités par des espaces).

Autres conseils

+ signifie l'addition numérique dans awk. Si vous souhaitez concaténer, placez simplement les constantes et / ou expressions séparées par des espaces.

Donc, ce

line += " " + $i

devrait devenir

line = line " " $i

EDIT: Iff Les fichiers journaux exim (je suis plus dans Postfix :) sont séparés par un seul espace, les éléments suivants ne sont-ils pas plus simples:

grep -F o\' /var/log/exim/main.log | cut -d\  -f20-33 >output.txt

?

" '" n'est pas illégal dans les parties locales. Dans la RFC2821 , section 4.1.2:

Local-part = Dot-string / Quoted-string

Dot-string = Atom *("." Atom)

Atom = 1*atext

2821 références supplémentaires RFC2822 pour les éléments non définis localement, ainsi:

atext           =       ALPHA / DIGIT / ; Any character except controls,
                        "!" / "#" /     ;  SP, and specials.
                        "<*>quot; / "%" /     ;  Used for atoms
                        "&" / "'" /
                        "*" / "+" /
                        "-" / "/" /
                        "=" / "?" /
                        "^" / "_" /
                        "`" / "{" /
                        "|" / "}" /
                        "~"

En d'autres termes, "&"; est un parfaitement légal non caraculé à avoir dans un email localpart. Il se peut que ce ne soit pas légal sur votre site , mais ce n'est pas ce que vous avez dit.

Désolé de ne pas rester directement sur le sujet, mais je voulais corriger votre affirmation.

Tâche éteinte et encore plus simple: python.

import fileinput
for line in fileinput.input():
    if "'" in line:
        fields = line.split(' ')
        print "> ", ' '.join( fields[20:34] )
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top