Il perl è un linguaggio di scripting nato per l'elaborazione di grandi quantità di testo ma poi evolu tosi ulteriormente: l'origine del suo nome sta infatti per Practical Extraction and Report Language. La differenza principale con uno script di shell in perl è che l'interprete del perl analizza completamente il programma prima di eseguirlo. - Filehandle del Perl Come ogni processo UNIX, anche il perl possiede i tre filehandle (STDOUT, STDERR, STDIN). Alcuni comandi come print utilizzano di default il terminale come standard output: print Scrivo sul terminale n ;# è analogo a: print STDOUT Scrivo sul terminalen ;# possiamo anche prelevare l'output di STDIN e metterlo su STDOUT while (<STDIN>){print STDOUT;}# ogni cosa che scrivo con la tastiera viene messa su schermo 1 / 16
L'operatore < > ossia maggiore-minore (o NULL) consente di trarre l'input da STDIN o da un file sulla linea di comando. while (<>){print;} # è una specie di cat CREAZIONE DI UN FILEHANDLE: Supponiamo che la variabile filename contenga il percorso di un file: open (FILE,$filename); die non posso aprire $filename ;# se esiste $filename apre il filehandle FILE Di default open apre un file in sola lettura (<), ma è possibile aprirlo in scrittura (>), lettura e scrittura (+>), accodamento (>>). 2 / 16
open (FILE, > $filename ); die non posso aprire $filename ; # lo apre in scrittura... # è possibile aprire un filehandle pipe di input o output# se nella shell si usava ls wc-l per contare i file in perl: open (INP, ls );while (<INP>) {++$files;}print ci sono $files nella directoryn # per ls wc mail $adress vediamo un altro esempio open (INP, ls );open (OUT, mail $adress )while (<INP>) {++$files;}print OUT ci sono $files nella directoryn - Variabili del Perl 3 / 16
VARIABILI SCALARI Come si è già potuto notare, le variabili scalari sono precedute dal simbolo del dollaro $. Esse assumono il significato di stringhe o valori numerici a seconda del contesto in cui appaiono. print Scrivi una variabile ;$var= <STDIN>chop $var;print la tua variabile è $varn ; La funzione chop taglia l'ultimo carattere di una stringa per eliminare il riorno a carrello (l'invio.. altrimenti sarebbe andato a capo da solo senza n..). Da notare che chop, se non viene specificato nessun argomento, opera su $_. La variabile $_ entra in gioco molto spesso, a volte senza che il programmatore se ne occupi: infatti è usata come variabile di default in moltissimi comandi (ad esempio in chop, con l'operatore diamante, con print etc..) ARRAY 4 / 16
Gli array vengono preceduti dal simbolo @. # definire un vettore anche con variabili miste è immediato: @vettore = (1,4.5, marco, ciao,$var)# anche richiamarlo è molto semplice: print ecco il vettore completo: @vettore n print ecco il terzo elemento: $vettore[2] n # e per sapere il numero di elementi che lo compongono: print è composto da $#vettore elementinprint ed il minimo indice è $[vettore Per richiamare una componente del vettore si usa il simbolo dollaro essendo essa una scalare... Un array molto importante è @ARGV: esso contiene i parametri digitati sulla linea di comando. NOTA: USO DI FOREACH: L'istruzione foreach viene utilizzata per scorrere un array ed assegnarne ad una variabile i diversi elementi, uno dopo l'altro: 5 / 16
foreach $var (0.. $#ARGV){print l' elemento $var è $ARGV[$var]n ; } # la variabile $var assume valori da zero al numero di elementi # dell' array.l'array in questione è @ARGV Riscriviamo questo esempio usando una delle funzioni della variabile $_: foreach(0.. $#ARGV){print l' elemento $var è $ARGV[$_]n ; } # non serve più la $var poiché di default $_ prende il suo posto OPERAZIONI CON GLI ARRAY 6 / 16
L'operatore shift elimina il primo elemento dell' array e quindi sposta verso sinistra tutto il suo contenuto restituendo l'elemento eliminato. Unshift aggiunge uno o più elementi all'inizio dell'array e restituisce il numero di elementi totali. @vettore = (1,4.5, marco, ciao,100) $memo = shift (@vettore) # ora @vettore =(4.5, marco, ciao,100) e $memo=1 $memo2 = unshift (@vettore, agg ) # ora @vettore =(agg,4.5, marco, ciao,100) e $memo2=5 Gli analoghi operatori pop e push si occupano degli spostamenti verso destra degli elementi: @vettore = (1,4.5, marco, ciao,100)$memo = push (@vettore, bello, brutto ) # ora @vettore =(4.5, marco, ciao,100,bello,brutto) e $memo=6 $memo2 = pop(@vettore) # ora @vettore =(4.5, marco, ciao,100,bello) e $memo2=brutto 7 / 16
Accenniamo anche agli operatori sort e reverse che si occupano di ordinare secondo la tabella ASCII i vettori: @numeri = (50,12,4,23,44,33,456);@ordinati=sort (@numeri);print @ordinati ; #Attenzione il nuovo ordine non è numerico:(12 23 33 4 44 456 50) Il comando split suddivide una stringa in base ad un dato modello, mentre join concatena una serie di stringhe. @campi = split (/:/,$linea) # se $linea è una linea del file passwd, tramite questo comando # creiamo un array contenente i vari record # per ricostruire tali record basta usare join: $line = join (':',@campi) L'operatore grep del perl è simile a quello di shell,ma può compiere azioni aggiuntive ed usare i test sui file: 8 / 16
@vettore = (1,4.5, marco, ciao,100);@num = grep(/[0-9]/,@vettore); # @num diventerà (1,4.5,100)# ma grep può anche compiere delle operazioni aritmetiche: @numperdue = grep (($_ *= 2),@num); # che diventa (2,9,200) Il comando splice ( ) viene utilizzato per la manipolazione degli array, esso ha una sintassi del tipo: splice (LIST, OFFSET,LENGHT,LIST) Prende come argomento dall'elenco LIST, e restituisce gli argomenti rimossi; lenght indica su quanti valori agire a partire dall'offset: questi possono essere opzionali. @vettore = (4.5, marco, ciao,100)splice (@array,0,0, agg1 ) # è analogo a $memo2 = unshift (@vettore, agg ) @vett = ( uno, due, otto, sette, cinque )@vecchi = splice (@vett,2,2, tre, quattro ); # abbiamo sostituito otto e sette con tre e quattro 9 / 16
# si noti che si conta gli offset da zero;# per ricostruire il vettore originale: splice (@vett,2,2,@vecchi); HASH o ARRAY ASSOCIATIVI Un array associativo utilizza una stringa precedentemente definita (chiave) per la sua ricerca. In perl si indica con il simbolo percentuale (%): %auto = ('marca','modello','porte','colore'); # se volessimo assegnargli un valore: $auto{'marca'} = 'fiat';# o tutti i valori in una volta si usa la virgola o =>: %auto = ('marca'=> fiat,'modello'=>punto,'porte'=>3,'colore'=>blu)print la marca dell'auto è $auto{'marca'}n ; 10 / 16
L'operatore keys produce un elenco delle chiavi ossia serve a stampare ogni chiave dell'array associativo e può essere ad esempio sfruttato cosi': foreach $var (keys(%auto)){print la chiave $var è $auto{$var} ;} # l'ordine di output di keys è imprevedibile e disordinato... L'operatore affine values restituisce ovviamentr tutti i valori del vettore...mentre each ritorna la coppia chiave-dato. Il seguente è uno script che rende evidente la comodità dell'uso degli hash: while ( <> ) { # prende in ingresso e mette in $_ @linea=split (/s/, $_); # array linea composto da parole foreach $parola (@linea){ # per ogni parola incrementa $parole++; #i due contatori $conta{$parola}++;}}foreach $parola (sort keys(%conta)) { # riordina.. print $conta{$parola} $parolan ; #..e stampa tutto} 11 / 16
print In totale trovate $parole parolenn ; VARIABILI PREDEFINITE Come gli script di shell, anche perl possiede delle utilissime variabili predefinite: $$ PID del programma 12 / 16
$< UID reale dell'utente $> UID effettivo dell'utente $? stato dell'ultima chiamata $_ argomento predefinito $0 nome del programma $ separatore di lista $/ separatore di righe per l'imput - Operatori di corrispondenza modelli Perl ha riunito, migliorato e semplificato le stesse funzioni delle utility di shell (sed,grep,awk) e le espressioni regolari che utilizza sono pressoche analoghe. $pattern = shift @ARGV;while (<>) { 13 / 16
print if (/$pattern/); # sottointeso if $_... } E' evidente che questo script è una specie di grep. Il primo parametro di ingresso è l'espressione regolare, quelli seguenti sono i file da analizzare riga per riga. Assieme al modello /espressione/ si usa l'operatore di corrispondenza =~ ogni volta che si desidera verificare la presenza di un modello in una variabile diversa da da $_. print nome? ;chop ($name =<STDIN>) #tutto in uno... è molto più elegante... if ($name =~ /marco$/i) blablabla# notiamo l'uso di //i ossia ignora maiuscolo-minuscolo # ed il simbolo $ ossia ancora la parola a fine riga# ma queste fanno parte delle espressioni regolari che vedremo.. - Operatori per stringhe 14 / 16
L'operatore punto '. ' serve a concatenare due stringhe mentre l'operatore ' x ' ha la funzione di ripetere delle stringhe, per esempio: $nomeintero=$nome..$cognome;$print ciao x 100;#stampa cento volte la stringa ciao Ricordiamo velocemente anche i seguenti semplici operatori: lenght: misura la lunghezza di una stringa reverse: inverte una stringa index, rindex: trovano la posizione della prima e dell'ultima occorrenza. $frase= la posizione delle parole è una posizione $pos1=index($frase, posizione ); $pos2=rindex($frase, posizione ); #quindi pos1=3 e pos2=33 15 / 16
L' operatore substr puo' sia estrarre che inserire stringhe ed ha la seguente forma: substr (ESPR, OFFSET, [LUNGHEZZA]) 16 / 16