Newsgroup: it.comp.os.linux.iniziare
Titolo: prelevare ultima parte del file

Ho un file cosě fatto:
stringa fissa
righe1
righe1
righe1
stringa fissa
righe2
righe2
.
.
.
stringa fissa
righeN
righeN
righeN
righeN
Ho bisogno di prelevare l'ultima parte del file a partire dall'ultima
occorrenza di "stringa fissa" fino alla fine del file.
C'č un modo semplice per farlo?
Un modo Lungo č
cat file|(while read a;do if [ $a = "stringa fissa" ];then echo $a >
/tmp/appoggio;else echo $a >> /tmp/appoggio;fi)
cat /tmp/appoggio č l'output che mi serve (ho improvvisato, non l'ho
provato).
C'č un modo piů "elegante" per farlo e comunque piů rapido (78000 righe
c.a. totali), tipo passarlo in | ad un sed....
Matteo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 /tmp/appoggio;else echo $a >> /tmp/appoggio;fi)
almeno usa tac!
tac cippa | (while read a; do if [ "$a" == "cippa" ]; then break; else
echo $a;  fi;  done;) > /tmp/appoggio
ma anche
tac file | sed '/^stringa fissa$/ q' dovrebbe funzionare
.a.
-- 
Il mattino ha l'oro in bocca. Il MATTino ha l'OrO In bOcca.
i lma tt ino ha l'o roin bocc a.ilmattinohal'oroinbocca. il ma tt in
oh al' or oi nb oc ca. il matti noha l'oroinbocca. IL MATtiNO Ha l'ORO
InBOCCa. I l m a t t i n o  h a l' o r o i n b o c c a . ilmattinohal'oroin
BoCcA. iLmAtTiNoHaL'oRoInBoCcA.

Matteo Rossini wrote:
tail -n \
`awk \
  'BEGIN {riga=0}
   /pippo/ {riga=NR}
   END {print NR-riga}'\
 pippo.txt ` \
pippo.txt
Ma perché non usi PERL?
-- 
Sabatino
*** Sequenza di reboot:
        Carol - Alt - Del

> Ma perché non usi PERL?
Perchè se awk è "questo sconosciuto" (lo conosco poco), perl non 
lo conosco per niente... e poi mi piace molto lo shell scripting.
awk lo uso, ma il mio utilizzo si limita a 
cat file|awk '{print $1,$2 " ciao " $3}'
Al massimo, qualche volta uso uno degli esempi già fatti nel man.
cmq lo script che mi hai dato funziona. Grazie!


 
Non conoscevo questa sintassi di sed; il mio uso (anche se massivo)
solitamente si limita a 's/stringa1/stringa2/g'
cmq lo script funziona a patto di aggiungerci un'altro |tac in coda,
altrimenti me li mostra in ordine inverso
tac file | sed '/^stringa fissa$/q' | tac
purtroppo sui miei sistemi non ho tac a disposizione e lo dovrei
sostituire con 
cat -n file |sort -rn|cut -c8-
che ha una complessità computazionale un po' più elevata di tac
(il mio script deve funzionare sia su linux sia su solaris e con shell
/bin/sh standard, infatti il mio script, provato con bash, in cui avevo
messo == è fallito perchè in /bin/sh si mette = invece di == )
Un'altro che mi è venuto in mente (solo elegante perchè in verità è più
lungo) è 
tail -`expr \`cat file|wc -l\` - \`grep -n "stringa fissa" file|tail -1|
                                   cut -f1 -d:\`` file


 
eccone un altro:
more +`grep -n "stringa fissa" file|tail -1|cut -f1 -d:` file|cat


 purtroppo sui miei sistemi non ho tac a disposizione e lo dovrei
fa parte delle coreutils, e comunque avra' un sorgente di  10 righe!
Non puoi ricompilartelo? :-)



Per ora ho usato una delle altre soluzioni.
Cmq ho scaricato i sorgenti delle coreutils e non sono proprio una decina di 
righe (qualche centinaio + gli include), considerando che va compilato con 
il makefile e che vuole una libreria e blah blah blah.
Ho fatto di meglio; sono andato sul sito ufficiare di sunfreeware dove si 
trovano i precompilati ufficiali; ho scaricato le coreutils e ne ho estratto 
il solo binario di tac, ma non so se lo userň per lo scopo (preferisco 
rimanere con quello che le distribuzioni hanno di ufficiale, altrimenti 
installerei le coreutils complete trasformando il SUN/solaris in GNU/Solaris 
:-)
Cmq. ho testato le performance dei vari script presentati, e su un file di 
5Mb e 80000 righe c.a., il mio primo script improvvisato impiegava c.a. 40 
secondi; lo script con l'awk di Sabatino, circa 3 secondi, alcuni degli 
altri sotto il secondo e sotto il mezzo secondo (valori indicativi... si sa 
che quando viene lanciato la seconda volta subentra la cache).
Sicuramente con tac verrebbe ancora meno, ma credo che questa settimana non 
avrň tempo di fare altre prove (domani mi aspetta un lavoraccio, di quelli 
supernoiosi, meccanici, non scriptabili, da fare su 100 macchine, e non 
scriptabili... entro mezzogiorno; uff... sono stanco solo a pensarci; per 
fortuna il pomeriggio sarň impegnato con qualcosa di piů difficile e 
rognoso... ma gratificante, trobleshooting su una anomalia di sendmail, solo 
su una macchina!!!, ma questa č un'altra storia...)
Matteo 

 altri sotto il secondo e sotto il mezzo secondo ...
Tutti questi algoritmi hanno difetti.
Se le prestazioni sono importanti l'unica
soluzione è ricorrere ad un linguaggio 
di scripting (PERL Ruby, Python...)


 di scripting (PERL Ruby, Python...)
Questo è vero, ma le prestazioni non sono il mio requisito.
Considera che è uno script che si deve accodare ad uno che dura anche un 
paio di ore.
Infatti inizialmente ci ho messo il primo che avevo fatto (quello con while, 
da 40 secondi)
e mi andava anche bene.
Tutta la discussione non era tanto sulle performance, ma sulla forma.
Comunque non su tutte le macchine (anzi, su poche) ho perl e su nessuna 
Python. Semmai mi faccio un programmino in C ad hoc, se voglio ottimizzare 
al massimo (o almeno credo che otterrei il massimo... a meno che non lo vado 
a scrivere in assembler :-).
Matteo