Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11

Discussione: Aiuto per script Perl

  1. #1

    Aiuto per script Perl

    Ciao, sono un neofita di Perl, sto cominciando ad usarlo per la tesi. Devo realizzare uno script che in pratica deve analizzare un file di testo, che non è altro che una sequenza di circa 1000 comandi linux (per esempio: sudo, ls, pwd, cd, ssh, ecc....), uno per ogni riga, le righe sono numerate. Quello che deve fare lo script è contare il numero di volte che è stato usato ogni comando e calcolare le distanze (minima, massima e media) tra un comando e ogni altro comando, per distanza intendo il numero di righe.
    Faccio un esempio:

    file di testo con i comandi:

    7 ls
    8 cd
    9 sudo
    10 ls
    11 ls
    12 more
    13 clear
    14 rm
    15 ls
    16 htmlview
    17 htmlview
    18 lsof
    19 cd
    20 ssh
    21 sudo

    Allora le distanze sono
    - ls e cd ---> minima=1 (posizioni 7 e 8),massima=4 (pos. 15 e 19),media=2.5
    - ls e sudo --> min=2 (pos 7 e 9), max=6 (pos. 15 e 21), media=4
    - ls e ls --> min=1 (pos 10 e 11), max=4 (pos. 11 e 25), media=2.5
    - ls e more ....................
    ecc..........

    non so se avete capito...
    avete qualke suggerimento??

  2. #2
    Utente di HTML.it
    Registrato dal
    May 2002
    Messaggi
    268
    Ma tu vuoi la soluzione o una dritta?
    Vabbèh, io comincerei con il trasformare il file in un array:

    open (FILE,"nome_file.txt");
    @RIGHE=<FILE>;
    close (FILE);

    poi imposterei delle variabili di partenza per il conteggio e quindi farei un ciclo foreach sull'array:

    $quanti_ls=0;
    $quanti_more=0;
    ...
    $dist_min_ls_cd=10000; #partendo alti perchè sul confronto si guarda il valore più basso (questa però è assurda, secondo me la minima sarà quasi sempre 1)
    ...

    foreach $RIGHE(@RIGHE)
    {
    #se nella riga c'è il numero di riga lo scorpori e lo metti in una variabile per calcolare le distanze
    chop $RIGHE; #togli il carattere "\n" di ogni riga
    @var=split(/ /,$RIGHE);
    $numero_tiga=$var[0];
    $comando=$var[1];

    #qui inserisci le condizioni che ricalcolano le variabili impostate
    if ($comando eq "ls")
    {$quanti_ls++}
    ...

    }

    alla fine stampi i risultati.

    Quello che non capisco è come mai all'università vi facciano usare il perl!!?!!!
    Pensavo che questo linguaggio fosse al tramonto.
    Fra l'altro è impossibile trovare dei libri sul perl!!!

  3. #3
    il perl all'università nn l'ho studiato, solo che devo usarlo per la tesi, poichè a quanto pare è il linguaggio che più si adatta per analisi di file di testo, grazie alle espressioni regolari...
    pensavo appunto che il suggerimento avrebbe compreso l'uso di espressioni regolari...
    cmq grazie per la dritta... vedrò di adattare il tuo codice e ti farò sapere...

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2002
    Messaggi
    268
    con le espressioni regolari mi viene in mente una cosa del genere.
    Metto il testo in una variabile
    $var="";

    open (TXT,"testo.txt");
    while (<TXT>)
    {
    #tolgo gli spazi
    $_ =~ s/ //g;
    #genero la variabile
    $var="$var$_";
    }
    close (TXT);

    #ora $var equivale al tuo testo
    #quanti ls ci sono?
    $quanti_ls = split(/ls\n/,$var)-1;

    per le distanze tra un comando e l'altro la faccenda si fa un po' più lunghetta (da parte mia!) per risponderti in 5min :master: ... Ci sono motli modi per risolvere, magari qui qualcuno ne tira fuori di migliori

  5. #5
    ok l'ho provato e funziona

    nn ho capito bene cosa fa il comando split, o meglio ho letto in una guida qual è la sua funzione, ma non capisco come lo hai usato tu...

    inoltre volevo kiederti, siccome la lista di comandi diversi è molto lunga, mi conviene scrivere le espressioni regolari a mano una ad una, oppure, cosa che ritengo forse più adatta, fare una procedura che riesca a trovare tutti i comandi differenti nel file e fare tutto in automatico, cioè per ogni tipo di comando tenersi il conteggio delle volte che è stato usato..

    ti ringrazio molto per l'aiuto

  6. #6
    Utente di HTML.it
    Registrato dal
    May 2002
    Messaggi
    268
    split serve per separare e genera un array (lo si usa anche in javascript):

    se avessi scritto

    @prova = split(/ls\n/,$var);

    avrei ottenuto un array contenente gli elementi divisi da "ls\n"
    Mettendolo così invece:

    $quanti_ls = split(/ls\n/,$var)-1;

    la variabile rappresenta il numero degli elementi da cui naturalmente devi togliere l'ultimo poichè non è seguito da un "ls\n"!

    Per quanto riguarda il ciclo normalmente io faccio così:
    1) genero un array contenente le variabili:
    @variabili=("ls","cd", ....);

    2) poi faccio un ciclo sull'array:
    foreach $variabile(@variabili)
    {
    #qui scrivo:
    $mom="quanti_$variabile"; #serve per definire il nome della variabile in uscita (es. $quanti_ls)
    ${$mom}= split(/$variabile\n/,$var)-1;
    }

    3) Così sei a posto.
    Attento però, accertati che il tuo compilatore perl non sia vecchissimo perchè altrimenti non considererebbe la forma ${$mom}!

  7. #7
    mhh... non so se mi conviene fare in questo modo perchè i comandi sono talmente tanti.... e poi vi è la possibilità di avere comandi con parametri (per es. "ssh 192.168.1.5", "more secure", ecc....), quindi sarebbe poco fattibile quello che dici tu.
    io avevo pensato ad un Hash che ha come chiavi i comandi (seguiti da eventuali parametri, quindi uno stesso comando ma con parametri diversi ha 2 chiavi distinte) e come valore il numero di volte che compare quel comando. Che ne pensi??
    Se per te è una buona idea come faccio ad attuarla??
    grazie 1000

  8. #8
    Utente di HTML.it
    Registrato dal
    May 2002
    Messaggi
    268
    ok. A quel punto farei così:
    prima cosa se il comando è seguito da un parametro devi trasformare

    ${$mom}= split(/$variabile\n/,$var)-1;

    in

    ${$mom}= split(/$variabile /,$var)-1;

    poichè \n viene conteggiato solo quando vai a capo.


    Per avere il conteggio dei comandi legati ai parametri invece secondo me, ti conviene usare una cosa di questo tipo:

    open (TXT,"file.txt");
    while (<TXT>)
    {
    # creo un array momentaneo utilizzando degli elementi divisi da uno spazio
    # es. la riga è -> 10 ssh 192.168.1.5 -> l'array sarà @mom=(10,'ssh','192...')
    @mom=split(/ /,$_);

    #definisco le variabili che contano i comandi
    $comando_unico=$mom[1];
    $comando_con_parametro="$mom[1]_$mom[2]";

    #incremento le variabili
    ${$comando_unico}++;
    ${$comando_con_parametro}++;

    #aggiungo il nome della variabile in un array solo se è la prima volta che la leggo
    if (${$comando_unico}==1) #le volte successive è > di 1
    {push (@elenco,$comando_unico)}
    if (${$comando_con_parametro}==1)
    {push (@elenco,$comando_con_parametro)}

    }
    close (TXT);

    # se i miei conti sono giusti alla fine hai @elenco che è il conteggio delle "comparsate":

    foreach $elenco(@elenco)
    {
    print qq{$elenco è comparsa ${$elenco} volte\n}
    }

    questo sistema però non ti fa usare le espressioni regolari ...

  9. #9
    Utente di HTML.it
    Registrato dal
    May 2002
    Messaggi
    268
    forse ti conviene aggiustare una cosa su $mom[2] dell'array visto che contiene caratteri strani e potrebbe non funzionare.

    Nell'esempio il parametro era 192.168.1.5, che diventerà il nome di una variabile così:

    $ssh_192.168.1.5

    sicuramente i puntini ti creeranno dei problemi. Quindi ti conviene piazzare subito dopo @mom=... una piccola espressione regolare del tipo:

    $mom[2] =~ s/\./_/g;

    e la variabile avrà come nome

    $ssh_192_168_1_5

    Possono esserci altri caratteri fastidiosi
    es. carattere "#"
    quindi aggiungi anche
    $mom[2] =~ s/\#/_/g;

  10. #10
    curiosità...che studi?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.