shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Formatação da saída com awk


From: Tiago Barcellos Peczenyj
Subject: Re: [shell-script] Formatação da saída com awk
Date: Sat, 26 Apr 2008 14:25:49 -0300

Euler,

vc pode usar sed para isso

$ sed -rn '/(^[^-]+-+).*/{s//\1/;h};
/^teste_/{s/.* ([^ ]+) +([^ ]+$)/\2 \1/;x;p;g;p}' arquivo.log
AAAA-------------
testetesteteste 38666
BBBB-------------
testetesteteste 26232207

Ok, ok, ta muito complicado, mas veja só:

$ sed -rn '/^[^-]+-+/h;/^teste_/{x;p;g;p}' log [^ ]+$)
AAAA-------------campo_1-------------campo_2-----campo_3----campo_4----------
teste_1 371508787 371547453 38666 testetesteteste
BBBB-------------campo_1-------------campo_2-----campo_3----campo_4----------
teste_2 4625081503 4651313710 26232207 testetesteteste

1) a opção -n serve para informar ao sed "imprima apenas quando eu mandar"
2) a opção -p serve para utilizar expressões regulares extendidas
(assim não preciso escapar o quantificador + , que significa "um ou
mais vezes", assim como os parentesis, para informar os grupos).

Eu fiz uma sacanagem. o comando h quarda o padrão num espaço chamado
espaço reserva, tipo uma memória do sed, sobreescrevendo. Assim no
espaço reserva eu tenho a ultima ocorrencia de uma linha do tipo,
 ^[^-]+-+      ,que traduzindo significa: tudo o que começa com um ou
varios caracteres diferentes de -, seguidos de um ou varios - (no caso
do AAAA------------- ... ).

Agora, quando eu encontro uma linha que começa com teste_ eu:

x) troco essa linha com a linha que esta na memória (a atual
'teste_...' vai, outra volta).
p) imprimo a linha que veio (AAAA---------- ...)
g) pego a linha da memória (teste_...)
p) imprimo a linha cachorrona

Só que não fica como vc quer. Ai vc precisa fazer a sacanagem:

"se uma linha NÃO tem o que eu quero, então eu a manipulo habilmente
até que ela chegue ao que eu quero"

Eu poderia ter usado varias tecnicas mas... uma vez com sed, podemos
continuar nele.

$ sed -rn '/(^[^-]+-+).*/{s//\1/;h};
/^teste_/{s/.* ([^ ]+) +([^ ]+$)/\2 \1/;x;p;g;p}' arquivo.log

eu transformei a primera ER em

(minha_ER).* -- ou seja, criei um grupo para o que me interessa. basta fazer

s/(minha_ER).*/\1/

para que toda a linha seja reduzida ao que a minha ER casa. em outras
palavras, eu apaguei o resto da linha.

na outra eu fui mais sacana pois eu tenho 2 grupos e troco toda a
linha pelos grupos, na ordem inversa. coisa de quem toma muito café e
não tem escrupulos.

Vamos ver a versão AWK?

$ awk '/^[^-]+-+/{match($0,/^[^-]+-+/); x=substr($0,1,RLENGTH)}
/^teste_/{print x,"\n"$5,$4}' arquivo.log
AAAA-------------
testetesteteste 38666
BBBB-------------
testetesteteste 26232207

x, nesse caso, armazena aquele pedaço da linha anterior, que eu
descobri o que é via match. match procura uma expressão regular numa
string, nesse caso em $0, e seta um valor na variavel RLENGTH, que é
onde a expressão acaba. basta pegar essa parte da string e guardar na
variavel x, que sera lida depois.

Aqui fala um pouco dessas duas funções:
http://people.cs.uu.nl/piet/docs/nawk/nawk_92.html

Eu poderia ter resolvido dessa forma também

$ awk '/^[^-]+-+/{sub(/-[^-]+.*/,"-");x=$0} /^teste_/{print x,"\n"$5,$4}' log
AAAA-------------
testetesteteste 38666
BBBB-------------
testetesteteste 26232207

Entretanto aqui eu faço uma substituição grosseira do resto da linha
que tem o AAAA------... por -, abusando do .* (e o fato dele ser
guloso). Parece mais simples, mas está sujeito à falhas, embora não
consigo pensar em nenhuma situação que seja possivem demonstrar.

Espero que tenha sido util (pra mim pelo menos foi, pois pude decorar
a função do comando x do sed e perdi o medo do RLENGTH do awk).

Abraços

T.

2008/4/25 Euler Mendes <address@hidden>:
>
>
>
>
>
>
> Galera,,,
>
>  tenho o seguinte log.:
>
>
> AAAA-------------campo_1-------------campo_2-----campo_3----campo_4----------
>  teste_1 371508787 371547453 38666 testetesteteste
>
>
> BBBB-------------campo_1-------------campo_2-----campo_3----campo_4----------
>  teste_2 4625081503 4651313710 26232207 testetesteteste
>
>  Estou a tentar usar o awk com a seguinte função :
>  awk '$1~"teste_" {print $5";"$4}' teste > teste_.csv
>
>  a funcao busca realmente o que desejo:
>  $5 $4
>  testetesteteste 38666
>  testetesteteste 6232207
>
>  porem,, gostaria que seprasse da forma:
>
>  AAAA-------------
>  testetesteteste 38666
>  BBBB-------------
>  testetesteteste 26232207
>
>  Alguém tem uma dica de como fazer???
>  Mto Obrigado
>
>
>  ---------------------------------
>  Abra sua conta no Yahoo! Mail, o único sem limite de espaço para
> armazenamento!
>
>  [As partes desta mensagem que não continham texto foram removidas]
>
>  



-- 
Tiago B Peczenyj
Linux User #405772

http://peczenyj.blogspot.com/
"what does not kill us makes us stronger"


reply via email to

[Prev in Thread] Current Thread [Next in Thread]