Newsgroup: it.comp.os.linux.iniziare
Titolo: awk stampare le 3 righe prima e le 3 dopo (emulare grep -C 3)

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.---------+

 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

 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
 

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.---------+

 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

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.


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.----------------+

 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
 

 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.---------------------------+

> 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
 

 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
      }'
 

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.---------+

 
 
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/