Guida per gli script Awk - Problema logico
Domanda
Attualmente sto scrivendo un semplice script .sh per analizzare un file di registro Exim per le stringhe corrispondenti " o '" ;. Attualmente, quando si visualizza output.txt, tutto ciò che c'è è uno 0 stampato su ogni riga (606 righe). Immagino che la mia logica sia sbagliata, poiché awk non genera errori.
Ecco il mio codice (aggiornato per problemi di concatenazione e contro). Modifica: ho adottato un nuovo codice dalla risposta di dmckee con cui sto lavorando con il vecchio codice a favore della semplicità.
awk '/o'\''/ {
line = "> ";
for(i = 20; i <= 33; i++) {
line = line " " $i;
}
print line;
}' /var/log/exim/main.log > output.txt
Qualche idea?
MODIFICA: Per chiarezza, sto chiedendo "quot" o " negli indirizzi email, perché "è un carattere illegale negli indirizzi email (e nei nostri database, appare solo con nomi con prefisso o).
MODIFICA 2: come da richiesta di commento, ecco un campione disinfettato dell'output desiderato:
[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
Il motivo per cui inizio a 20 nel mio ciclo è perché tutto ciò che precede il 20 ° campo sono solo informazioni di registro standard che non sono necessarie per i miei scopi qui. Tutto ciò di cui ho bisogno è tutto dall'IP e oltre per questa soluzione (i messaggi per ogni errore 550 sono diversi per ogni server di posta in uso là fuori. Sto compilando un elenco di quelli comuni)
Soluzione
Non c'è davvero bisogno del grep qui. Consenti a awk di selezionare le linee corrispondenti per te (e correggere il tuo bug di concatenazione come da & # 932; & # 918; & # 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
Certo, alla fine avrai bisogno di una strana fuga se lo fai al prompt come sopra. È più pulito in uno script ...
Modifica: al primo passaggio ho perso il problema + = ...
Supponendo anche che la linea che hai indicato sopra sia parziale, poiché ha solo 13 campi (per impostazione predefinita i campi sono delimitati da spazi bianchi).
Altri suggerimenti
+
significa aggiunta numerica in awk. Se si desidera concatenare, posizionare semplicemente le costanti e / o le espressioni separate da spazi.
Quindi, questo
line += " " + $i
dovrebbe diventare
line = line " " $i
EDIT: Iff i file di registro exim (sono più interessato a Postfix :) sono separati da un singolo spazio, non è il seguente più semplice:
grep -F o\' /var/log/exim/main.log | cut -d\ -f20-33 >output.txt
" '" non è illegale nelle parti locali. Da RFC2821 , sezione 4.1.2:
Local-part = Dot-string / Quoted-string
Dot-string = Atom *("." Atom)
Atom = 1*atext
2821 ulteriori riferimenti RFC2822 per elementi non definiti localmente, quindi:
atext = ALPHA / DIGIT / ; Any character except controls,
"!" / "#" / ; SP, and specials.
"<*>quot; / "%" / ; Used for atoms
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
In altre parole, " '" è un non quotato perfettamente legale che può essere inserito in una email localpart. Ora, potrebbe non essere legale sul tuo sito , ma non è quello che hai detto.
Ci scusiamo per non rimanere direttamente sull'argomento, ma volevo correggere la tua affermazione.
Off task, e ancora più semplice: python.
import fileinput
for line in fileinput.input():
if "'" in line:
fields = line.split(' ')
print "> ", ' '.join( fields[20:34] )