Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

awk stampare le 3 righe prima e le 3 dopo (emulare grep -C 3)

134 views
Skip to first unread message

BIG Umberto

unread,
Sep 29, 2017, 12:31:49 PM9/29/17
to
Da un log lunghissimo:

awk '( $4 ~ "ICMP" ) || ( $4 ~ "UDP" && $0 ~ ",1900 - " ) || ( $4 ~ "UDP" && $8
~ ",334.." ) { print $0 }'

Estraggo le righe che mi interessano, ma vorrei poter vedere anche le 3 prima e
le 3 dopo e separare i gruppi come fa grep, da una riga con i trattini.

In alternativa, fare la stessa cosa con grep?

Nota, i campi sono separati da 1,2,3 spazi.
In rete ho trovato solo esempi di come stampare con awk solo la riga precedente
o solo la riga successiva.

--
+---------------------------------------------------------------------------+
| Sappi che la mia spocchiosita' depressiva con pulsione |
| all'autodemolizione e' allo studio di menti brillanti del mondo della |
| psichiatria. Hanno promesso di spiegarmi che cosa ho detto. |
+-----#17--------------------Campagna contro le pubblicita` idiote.---------+

Piergiorgio Sartor

unread,
Sep 29, 2017, 3:08:31 PM9/29/17
to
On 2017-09-29 18:31, BIG Umberto wrote:
> Da un log lunghissimo:
>
> awk '( $4 ~ "ICMP" ) || ( $4 ~ "UDP" && $0 ~ ",1900 - " ) || ( $4 ~ "UDP" && $8
> ~ ",334.." ) { print $0 }'
>
> Estraggo le righe che mi interessano, ma vorrei poter vedere anche le 3 prima e
> le 3 dopo e separare i gruppi come fa grep, da una riga con i trattini.

Non e` proprio banale, lo avevo fatto una
volta, ma si devono considerare diversi casi.
Per esempio se si ha sovrapposizione di linee,
oppure se si e` all'inizio (o fine).

> In alternativa, fare la stessa cosa con grep?

A parte l'uso dei field, che non credo grep abbia.

> Nota, i campi sono separati da 1,2,3 spazi.
> In rete ho trovato solo esempi di come stampare con awk solo la riga precedente
> o solo la riga successiva.

Io farei stampare a "awk" *tutte* le righe,
ma metterei, in fronte a quelle "interessanti",
un "marker" univoco.

Poi, in pipe, con "grep -C" andrei a prendere
quel "marker" +/-3 linee intorno (che sono presenti,
dato che si stampa sempre tutto).

bye,

--

piergiorgio

Yoda

unread,
Sep 29, 2017, 3:24:57 PM9/29/17
to
Addi' 29 set 2017 16:31:47, BIG Umberto scrive:

> Da un log lunghissimo:

> awk '( $4 ~ "ICMP" ) || ( $4 ~ "UDP" && $0 ~ ",1900 - " ) \
> || ( $4 ~ "UDP" && $8 ~ ",334.." ) { print $0 }'

> Estraggo le righe che mi interessano, ma vorrei poter vedere anche le 3
>prima e
> le 3 dopo e separare i gruppi come fa grep, da una riga con i trattini.

> In alternativa, fare la stessa cosa con grep?

> Nota, i campi sono separati da 1,2,3 spazi.
> In rete ho trovato solo esempi di come stampare con awk solo la riga
> precedente
> o solo la riga successiva.

Se non ho capito male, una soluzione puo' essere di dare in pasto
a "grep -3" l'uescita di awk, no?
Ad esempio butti l'output di awk sul file pippo e poi "grep -3f pippo
origine". Ciao

--
bye, Yoda

BIG Umberto

unread,
Sep 29, 2017, 3:45:38 PM9/29/17
to
Piergiorgio Sartor in data 21:06, venerdì 29 settembre 2017, nel gruppo
it.comp.os.linux.iniziare ha scritto:
Ottimo suggerimento:




cat /tmp/log |\

awk '{ if ( ( $4 ~ "ICMP" ) || ( $0 ~ ",1900 - " ) || ( $4 ~ "UDP" && $8
~ ",334.." ) ) print $0, "+" ; else print $0 }' |\

grep -C 3 --color=never "+" |\

awk '{ s = "" ; \
if ( $4 ~ "ICMP" ) s = "\033[105;30m" ; \
if ( $0 ~ ",1900 - " ) s = "\033[40;36m" ; \
if ( $4 ~ "UDP" && $8 ~ ",334.." ) s = "\033[40;36m" ; \
if ( s != "" ) NF = NF - 1 ; \
printf "%0s%-s\033[0m\n", s, $0 }' |\
awk 'BEGIN { FS = ":" } { conteggioRighe = conteggioRighe +1; print $0 } END \
{ print "------------------------------"; print "Totale: " conteggioRighe "
voci."}'





Evidenzio poi le righe che mi interessano con colori diversi e tolgo il
marcatore "+".


--
+---------------------------------------------------------------------------+
| Il Pascal e' un linguaggio giocattolo fatto per insegnare la |
| programmazione ai matematici. |
+-----#20-------------------------------------Diamanti di saggezza.---------+

Piergiorgio Sartor

unread,
Sep 29, 2017, 4:03:44 PM9/29/17
to
On 2017-09-29 21:45, BIG Umberto wrote:
[...]
> cat /tmp/log |\
>
> awk '{ if ( ( $4 ~ "ICMP" ) || ( $0 ~ ",1900 - " ) || ( $4 ~ "UDP" && $8
> ~ ",334.." ) ) print $0, "+" ; else print $0 }' |\
>
> grep -C 3 --color=never "+" |\
>
> awk '{ s = "" ; \
> if ( $4 ~ "ICMP" ) s = "\033[105;30m" ; \
> if ( $0 ~ ",1900 - " ) s = "\033[40;36m" ; \
> if ( $4 ~ "UDP" && $8 ~ ",334.." ) s = "\033[40;36m" ; \
> if ( s != "" ) NF = NF - 1 ; \
> printf "%0s%-s\033[0m\n", s, $0 }' |\
> awk 'BEGIN { FS = ":" } { conteggioRighe = conteggioRighe +1; print $0 } END \
> { print "------------------------------"; print "Totale: " conteggioRighe "
> voci."}'
>
>
>
>
>
> Evidenzio poi le righe che mi interessano con colori diversi e tolgo il
> marcatore "+".

Il "+" lo metterei all'inizio oppure alla fine.
Il "grep", quindi, andrebbe o grep "^+", oppure grep "+$".

Questo per evitare "+" che siano in mezzo al testo.
Volendo, si puo` anche usare "+++".

bye,

--

piergiorgio

BIG Umberto

unread,
Sep 29, 2017, 4:27:50 PM9/29/17
to
Piergiorgio Sartor in data 22:02, venerdì 29 settembre 2017, nel gruppo
it.comp.os.linux.iniziare ha scritto:
Il marcatore "+" non compare in nessuna parte del file, per cui lo posso
mettere tranquillamente, giusta comunque l'osservazione sul grep.
Mettendolo alla fine, ho il vantaggio di non spostare i campi, e con la
semplice operazione NF = NF - 1, lo elimino dalla stampa in uscita, che passa
anch'essa tramite awk.

BIG Umberto

unread,
Sep 29, 2017, 4:33:32 PM9/29/17
to
Yoda in data 21:24, venerdì 29 settembre 2017, nel gruppo
it.comp.os.linux.iniziare ha scritto:
Esatto, come ha detto Piergirgio, con awk estraggo le righe che mi interessa, e
le marco con un marcatore, poi con grep -C 3 , ricavo il gruppo -3|+3 che mi
serve.
Peró mettendo tutto in pipe, non passo da files di appoggio (che aborrisco).

Vedi anche le risposte a Piergiorgio.

--
+---------------------------------------------------------------------------+
| Non fare domani quello che devi fare oggi, ma soprautto |
| non fare oggi quello che puoi fare domani... |
+-----#21---------------------------------Saggezze popolari.----------------+

Yoda

unread,
Sep 29, 2017, 5:25:14 PM9/29/17
to
Addi' 29 set 2017 20:33:30, BIG Umberto scrive:

> Vedi anche le risposte a Piergiorgio.

Si' l'ho vista dopo ed e' migliore anche perche' apre una sola volta il
file origine ciao!
Ma, per i "---" di separazione cui tenevi, non ti conviene dare grep -3
invece del tag +- 3 ? bah.. forse e' lo stesso, bisogna provare, lo
vedrai tu ariciao

--
bye, Yoda

BIG Umberto

unread,
Oct 1, 2017, 12:25:43 PM10/1/17
to
Yoda in data 23:25, venerdì 29 settembre 2017, nel gruppo
it.comp.os.linux.iniziare ha scritto:

> Si' l'ho vista dopo ed e' migliore anche perche' apre una sola volta il
> file origine ciao!
> Ma, per i "---" di separazione cui tenevi, non ti conviene dare grep -3
> invece del tag +- 3 ? bah.. forse e' lo stesso, bisogna provare, lo
> vedrai tu ariciao


Forse non ho capito, cosa intendi per:
> dare grep -3 invece del tag +- 3



Volendo vedere le 3 righe prima & le 3 righe dopo, quindi simmetrico, uso
l'opzione -C della riga di comando di grep.
I trattini di separazione, grep li mette in automatico.
Mentre se ci fosse stata una soluzione "tutta awk" i trattini, o comunque
un "qualcosa" di separazione li avrei dovuti mettere io (un banale print).



Il "giochetto" mi serve, quando leggo il log del router per evidenziare certi
pacchetti che vengono loggati e vedere "nell'intorno" cosa succede, per
esempio se ricevo un ping ed immediatamente un accesso al server, oppure se é
in corso un attacco firework o un traceroute.

Il primo awk marca i pacchetti chiave, poi il grep mostra l'intorno del
pacchetto, infine in secondo awk evidenzia con colori i 3 casi che mi
interessano e toglie il marcatore.

:)

--
+----------------------------------------------------------------------------+
| Crapa pelada fa 'l purcel co' la dona dei so fradel. |
| So fradel l'han ciapa, crapa pelada a'l bus slarga' |
+-----#39--------------------Diamanti di saggezza.---------------------------+

Yoda

unread,
Oct 1, 2017, 1:19:23 PM10/1/17
to
Addi' 01 ott 2017 16:25:42, BIG Umberto scrive:
> Yoda in data 23:25, venerdì 29 settembre 2017, nel gruppo
> it.comp.os.linux.iniziare ha scritto:

>> Si' l'ho vista dopo ed e' migliore anche perche' apre una sola volta il
>> file origine ciao!
>> Ma, per i "---" di separazione cui tenevi, non ti conviene dare grep -3
>> invece del tag +- 3 ? bah.. forse e' lo stesso, bisogna provare, lo
>> vedrai tu ariciao

> Forse non ho capito, cosa intendi per:
>> dare grep -3 invece del tag +- 3

Scusa ero distratto io, "-C 3" e' lo stesso di "-3". Ciao e grazie per la
risposta alla curiosita' mia!

--
Yoda

pec...@pascolo.gavoi.it

unread,
Oct 5, 2017, 9:39:06 AM10/5/17
to
BIG Umberto <nom...@nospam.invalid> writes:

> Da un log lunghissimo:
>
> awk '( $4 ~ "ICMP" ) || ( $4 ~ "UDP" && $0 ~ ",1900 - " ) || ( $4 ~ "UDP" && $8
> ~ ",334.." ) { print $0 }'
>
> Estraggo le righe che mi interessano, ma vorrei poter vedere anche le 3 prima e
> le 3 dopo e separare i gruppi come fa grep, da una riga con i trattini.
>
> In alternativa, fare la stessa cosa con grep?
>
> Nota, i campi sono separati da 1,2,3 spazi.
> In rete ho trovato solo esempi di come stampare con awk solo la riga precedente
> o solo la riga successiva.

awk ' {a[NR]=$0
if($0~"put") for(j=NR-3;j<=NR+3;j++) ins[j]=1
# ^^^^^^^^ il tuo test va qui, ho testato un file con molti "put"
}
END {
printing=0 ; first=1
for(i=1;i<=NR;i++)
if(ins[i]==1){
if(!printing){
if(!first) print "------------"
printing=1
first=0}
print i, a[i]}
else
if(printing) printing=0
}'

BIG Umberto

unread,
Oct 5, 2017, 11:17:22 AM10/5/17
to
pec...@pascolo.gavoi.it in data 15:39, giovedì 05 ottobre 2017, nel gruppo
it.comp.os.linux.iniziare ha scritto:
Geniale!
Dato che il numero di riga non mi interessa ho lasciato il solo "print a[i]"
come comando di stampa!

Peró nell' "else" secondo me si puó omettere l' "if" e lasciare il
solo "printing=0"

--
+---------------------------------------------------------------------------+
| Benventi sull'autostrada Milano Cavenago Trezzo Capriate Dalmine Bergamo |
| Seriate Grumello Oglio Palazzolo Rovato Ospitaletto Brescia Desenzano |
|Sirmione Peschiera Sommacampagna Verona Soave Montebello Montecchio Vicenza|
+-----#9---------------------Campagna contro le pubblicita` idiote.---------+

Aqua...@despammed.com

unread,
Oct 13, 2017, 9:05:28 AM10/13/17
to
Il giorno 29/09/2017 18:31, "BIG Umberto" ha scritto:


>
> Da un log lunghissimo:
>

Sostituisci la condizione $1 == "xxx" con la tua.
Se ti fa orrore usare quattro variabili puoi risistemare il codice per
usare un array.

BEGIN {
more = 0; a3=a2=a1=a0="";
}

{
a3=a2; a2=a1; a1=a0; a0=$0;
if (more > 0) { print $0; more--; }
}

$1 == "xxx" {
if (a3) print a3; if (a2) print a2; if (a1) print a1;
print $0;
more = 3;
}

Non copi



--
Lime and limpid green, a second scene
A fight between the blue you once knew
Floating down, the sound resounds
Around the icy waters underground

http://fuffologia.wordpress.com/
0 new messages