Awk scripting ajuda - Logic Issue
Pergunta
Atualmente estou escrevendo um script .sh simples para analisar um arquivo de log Exim para cordas correspondentes "o'". Actualmente, quando a visualização resultado.txt, tudo o que é existe um 0 impresso em cada linha (606 linhas). Eu estou supondo que a minha lógica está errada, como awk não lançar quaisquer erros.
Aqui está o meu código (atualizado para questões de concatenação e contador). Edit:. Eu adotei um código novo de resposta de dmckee que eu estou trabalhando agora com sobre o antigo código em favor da simplicidade
awk '/o'\''/ {
line = "> ";
for(i = 20; i <= 33; i++) {
line = line " " $i;
}
print line;
}' /var/log/exim/main.log > output.txt
Todas as idéias?
EDIT:. Por uma questão de clareza, estou grepping para "o '" em endereços de e-mail, porque "é um caractere ilegal em endereços de correio electrónico (e em nossos bancos de dados, aparece apenas com nomes prefixados-o')
EDIT 2: conforme o pedido comentário, aqui é uma amostra higienizado de alguma saída desejada:
[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
A razão que eu estou começando a 20 no meu laço é porque tudo antes do campo 20 é apenas informações de log padrão que não é necessário para os meus propósitos aqui. Todos necessidade I é tudo, desde o IP e além para esta solução (as mensagens para cada erro 550 são diferentes para cada servidor de correio em uso por aí. Estou compilando uma lista de mais comuns)
Solução
Não há nenhuma necessidade real para o grep aqui. Vamos awk selecionar as linhas de harmonização para você (e fixação de seu bug concatenação como por ??O?????):
awk '/o'\''/ {
line = "> ";
for(i = 20; i <= 33; i++) {
line = line " " $i;
}
print line;
}' /var/log/exim/main.log > output.txt
Claro, você acabar precisando de algum escape estranho se você fazê-lo no promp como acima. É mais limpo em um script ...
Edit: Na primeira passagem que eu perdi a + = problema ...
Também assumindo que a linha que dei acima é parcial, já que tem apenas os campos 13ish (por campos padrão são branco espaço delimitado).
Outras dicas
+
significa adição numérica em awk. Se você quiser concatenar, basta colocar as constantes e / ou expressões separadas por espaços.
Assim, este
line += " " + $i
deve tornar-se
line = line " " $i
EDIT: Iff arquivos de log exim (estou mais para Postfix :) são separados por um único espaço, não é o seguinte mais simples:
grep -F o\' /var/log/exim/main.log | cut -d\ -f20-33 >output.txt
?
"'" não é ilegal em partes locais. De RFC2821 , seção 4.1.2:
Local-part = Dot-string / Quoted-string
Dot-string = Atom *("." Atom)
Atom = 1*atext
2821 outras referências RFC2822 para elementos não definida localmente, de modo:
atext = ALPHA / DIGIT / ; Any character except controls,
"!" / "#" / ; SP, and specials.
"$" / "%" / ; Used for atoms
"&" / "'" /
"*" / "+" /
"-" / "/" /
"=" / "?" /
"^" / "_" /
"`" / "{" /
"|" / "}" /
"~"
Em outras palavras, "'" é um unquoted perfeitamente legal characted ter em uma localpart e-mail. Agora, ele pode não ser legal em seu site , mas isso não é o que você disse.
Desculpe por não ficar directamente sobre o tema, mas eu queria corrigir a sua afirmação.
tarefa Off, e mais simples ainda:. Python
import fileinput
for line in fileinput.input():
if "'" in line:
fields = line.split(' ')
print "> ", ' '.join( fields[20:34] )