Newsgroup: it.comp.os.linux.iniziare
Titolo: riformattare output .. con awk?

in merito al post sopra, vorrei generare un log di temperature che poi 
possa essere preso comodamente da gnuplot
in sostanza, ad ogni ora accodo al file di log un report di questo tipo
-------------
1184763601
20070718-1500
smsc47b397-isa-0a80
Adapter: ISA adapter
temp1:       +43Â°C
temp2:       +37Â°C
temp3:       +36Â°C
temp4:        +0Â°C
fan1:     2202 RPM
fan2:       82 RPM
fan3:       82 RPM
fan4:     2462 RPM
+++++++++++++
(la prima riga è un tempo in secondi, la seconda è data e ora, dalla 
terza ho l'output di sensors)
Io vorrei generare, in luogo di questo output, qualcosa di più 
comprensibile da parte di gnuplot, tipo:
1184763601 20070718-1500 43 37 36 0 2202 82 82 2462
avevo pensato ad awk, solo che se non ho capito male awk processa una 
sola riga alla volta...
Se si può (devo verificare), potrei fare un parser condizionale, tipo:
BEGIN { c = 0; }
{
   if ($0 = "-----------")  /*o strcmp che dir si voglia (?) */
	{
	c=1;
	goto end;
	}
  if (c=1)
	{
	printf("%d",$0)			/* tempo in secondi*/
         goto end
	}
...eccetera
  if (c=13)  /* linea dei ++++*/
	{
	printf("\n");
         goto end
	}
end:
	c=c+1
);
si può fare così? c'è qualche soluzione più brillante? oppure devo 
ricorrere a quei cosi che ho adoperato una volta di cui non ricordo più 
nulla che si chiamo lex e yacc e non mi ricordo neanche piu quale dei 
due servirebbe a me in questo caso? o basta vedere meglio gnuplot che 
adeguatamente istruito prende in input anche il file originale?
ciao e grazie e chi vorrà cimentarsi :-)
  BQ

 +++++++++++++
Se tu potessi configurare sensors affinché ti desse un output solo un po' 
diverso, e cioè:
-------------
1184763601
200707181500
temp1:       +43
temp2:       +37
temp3:       +36
temp4:        +0
fan1:     2202
fan2:       82
fan3:       82
fan4:     2462
+++++++++++++
(nota l'assenza di spazi a fine riga), ci sarebbe una soluzione 
semplicissima:
sensors | grep -o [0-9]*$ | fmt -u -w 100 >> file.per.gnuplot
Su tale file arriverebbero righe come:
1184763601 200707181500 43 37 36 0 2202 82 2462
Certamente sarebbero possibili regexp più raffinate: io ho perso 
familiarità. :(
-- 
Bye, Lem
Ceterum censeo ISLAM esse delendum
__________________________________
Combatti l'AIDS col tuo computer: 
http://fightaidsathome.scripps.edu/

 sola riga alla volta...
Sono sicuro che si può fare con awk, avevo visto uno script che lo
faceva, adesso vedo se lo trovo... trovato, non ho idea di come faccia,
ma prende i dati da due righe e li mette a fianco. Vedi se ti serve da
ispirazione (penso che il trucco stia nell'usare il printf senza il \n)
for calc in $CALCLIST; do
awk -v calc=$calc -v occ=$occ -v first=$first -v last=$last '
/     1 0     2S   1\(/ {sae=$6; sps=$7}
/     2 1     2P   1\(/ {pae=$6; pps=$7}
/dEtot_ae/ {eae=$3}
/dEtot_ps/ {eps=$3}
END {
if (calc==first) printf "%f ", occ >>"s.dat";
if (calc==first) printf "%f ", occ >>"p.dat";
if (calc==first) printf "%f ", occ >>"e.dat";
if (calc==first) printf "%f ", sae >>"s.dat";
if (calc==first) printf "%f ", pae >>"p.dat";
if (calc==first) printf "%f ", eae >>"e.dat";
printf "%f ",sps-sae >>"s.dat";
printf "%f ",pps-pae >>"p.dat";
printf "%f ",eps-eae >>"e.dat";
if (calc==last) printf "\n" >>"s.dat";
if (calc==last) printf "\n" >>"p.dat";
if (calc==last) printf "\n" >>"e.dat";
}' $calc/$calc.tst_$occ.out
done
done
-- 
Lorenzo `paulatz' Paulatto
Trieste
``Grandissima mi par l'inezia di coloro che vorrebbero che Iddio avesse
fatto l'universo più proporzionato alla piccola capacità del lor discorso.''
     --Galileo Galilei (Opere VII)

 familiarità.
Per ignorare spazi vuoti finali si può usare, mi pare:
sensors | egrep -o '[0-9]+ *'$ | fmt -u -w 100 >> file.per.gnuplot
Per evitare del tutto la riformattazione del tuo output di sensors, 
sarebbero necessarie le Perl-regexp... ma, generalmente, grep dev'essere 
ricompilato per poterle gestire.


 processa una sola riga alla volta...
Hai capito male, awk processa un record alla 
volta. Solo che per default il separatore di 
record e` una newline quindi...
Ora se ridefinisci il separatore di campi 
includendo una newline puoi trattare record
che si estendono molteplici linee. 
Ovviamente devi ridefinire anche il separatore 
di record quindi...
Hint: i separatori possono essere delle 
espressioni regolari

 
grazie a tutti, se ce la faccio vi posto lo script :-)

 record e` una newline quindi...
Grazie per la dritta; sono già a buon punto, usando questo script sul 
mio file,
BEGIN { c = 0; RS="---+"; FS="\n"; }
{
   if (c==0)
   {
         printf("\n\nnome del file: %s\n\n",FILENAME);
   }
   c++;
   printf("***************\nRECORD %d (%d)\n",FNR,c);
   for(i=1;i<NF;i++)
   {
         printf("Field %2d: %s\n",i,$i);
   }
}
interpreta correttamente i miei record multilinea, separati da 3 o più 
caratteri '-', i cui campi sono separati da dei newline
grazie ancora :-)

 grazie ancora :-)
ok, funziona :-) !!!!
ho giocato un po' sporco per togliere senza troppi patemi il °C (l'ho 
definito come separatore di campo...), a chi servisse incollo qui lo script
BEGIN { c = 0; RS="---+"; FS="\+|\n| +|Â°C"; }
{
      printf("%d %s %d %d %d %d %d %d %d %d 
%d\n",$2,$3,$4,$11,$15,$19,$23,$26,$29,$32,$35);
}
RS definisce il separatore di record (3 o più trattini)
FS il separatore di campo (un + oppure una newline oppure uno o piu 
spazi oppure l'indicatore di gradi celsius (hihi)
sto awk è veramente semplice e potente!
ciao

       printf("%d %s %d %d %d %d %d %d %d %d
print $2, $3, $4, $11, $15, $19, $23, $26, $29, $32, $35
Vedi sopra.

 
ok! grazie, così è più pulito :-)
ciao