Notizia:
  • Rilasciata Precise Pangolin 12.04. Per ottenerla, visitate questa pagina, oppure provate il tour dal vivo con un browser web moderno.
  • Nuovo forum di Ubuntu-it, l'annuncio. È consigliato aggiornare il proprio profilo e controllare la sezione Gruppo Forum per problemi noti.
  • Rilasciata la versione italiana di Precise Pangolin 12.04. Per maggiori informazioni, consultare questa discussione.
  • Il vincitore del Concorso desktop del mese di aprile è Jerico. L'elenco dei precedenti vincitori è qui.
  • È uscito il numero 17 della Newsletter italiana di Ubuntu. Lo trovate a questo indirizzo.
  • È uscito il numero 59 di Full Circle Magazine in italiano. Lo trovate a questo indirizzo.

[Risolto] [Bash] Inserire e cancellare utenti da file di configurazione

Linguaggi di programmazione: php, perl, python, C, bash, ecc.

[Risolto] [Bash] Inserire e cancellare utenti da file di configurazione

Messaggioda mikecesure » giovedì 2 febbraio 2012, 23:16

Ciao a tutti,
premetto che sono un quasi neofita del linguaggio bash, per questo cerco aiuto  ;D
Comunque, io avrei necessità di leggere un file riga per riga e poi, all'incontro di determinati caratteri, eseguire certe azioni per un certo numero di volte, fino a quando la riga non contiene un altro set di caratteri che bloccano questa sorta di ciclo.

Grazie anticipate  :)
Ultima modifica di mikecesure il lunedì 13 febbraio 2012, 17:42, modificato 1 volta in totale.
mikecesure
Prode Principiante
 
Messaggi: 186
Iscrizione: ottobre 2009

Re: [Bash] Leggere file riga per riga

Messaggioda Laycastle » venerdì 3 febbraio 2012, 0:25

una possibilità è:
Codice: Seleziona tutto
#!/bin/bash
while read riga ; do
   ....
done < $1

se sei più specifico si possono provare anche altre soluzioni.

Ciao :)
Ultima modifica di Anonymous il venerdì 3 febbraio 2012, 0:27, modificato 1 volta in totale.
la via più breve tra due punti è l'arabesco.
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1113
Iscrizione: aprile 2011
Località: Torino
Distribuzione: Gentoo ~amd64
Desktop: KDE 4.8

Re: [Bash] Leggere file riga per riga

Messaggioda patel » venerdì 3 febbraio 2012, 10:28

se ti rimane difficile capire l'esempio precedente
Codice: Seleziona tutto
while read riga; do
  echo $riga
  p=${riga:0:1} # primo carattere della riga
#  echo $p
  if [ $p == "X" ]; then exit; fi # se la riga inizia per X blocca il ciclo
done < testo # file da leggere
Ultima modifica di patel il venerdì 3 febbraio 2012, 12:30, modificato 1 volta in totale.
Un titolo ben azzeccato attira l'attenzione degli esperti in quel campo, fa risparmiare tempo a voi, aumenta la probabilità di successo.
patel
Accecante Asceta
Accecante Asceta
 
Messaggi: 23729
Iscrizione: aprile 2008
Località: Livorno

Re: [Bash] Leggere file riga per riga

Messaggioda toro2k » venerdì 3 febbraio 2012, 12:40

A seconda di quello che vuoi fare sed o awk potrebbero essere una soluzione migliore.
Altrimenti rilancio con
Codice: Seleziona tutto
cat il_file_che_ti_pare | while read line; do
  # ...
done

Che e` del tutto equivalente al ciclo che ti hanno gia` proposto me che, personalmente, preferisco perche' mantiene l'informazione circa "dove ne vengono le righe che stai leggendo" nell'intestazione del ciclo; secondo me e` piu` leggibile, soprattutto se il corpo del ciclo tende a diventare lungo.
Software is meant to be soft!
Avatar utente
toro2k
Prode Principiante
 
Messaggi: 24
Iscrizione: gennaio 2012

Re: [Bash] Leggere file riga per riga

Messaggioda l3on4rdo » venerdì 3 febbraio 2012, 13:27

Concordo con il fatto che sed e awk possano essere delle soluzioni migliori, anche perché già loro operano linea per linea.
Mentre, rispetto a:
Codice: Seleziona tutto
cat il_file_che_ti_pare | while read line; do
  # ...
done

è preferibile:
Codice: Seleziona tutto
while read riga ; do
   ....
done < il_file_che_ti_pare

Il motivo è che il primo metodo prevede prima la lettura del file con cat, poi il passaggio dell'output al ciclo while.
Il secondo metodo invece non "perde tempo" con il cat e inizia direttamente a produrre quanto voluto.
Inoltre, ma questa è questione questionabile, il secondo metodo è esteticamente più bello.

ciao
Ultima modifica di l3on4rdo il venerdì 3 febbraio 2012, 13:35, modificato 1 volta in totale.
Come da regolamento, UNA DISCUSSIONE, PER OGNI PROBLEMA, DOPO aver verificato, con UNA RICERCA, che non sia stato già trattato.
E, prima di sparire con la soluzione, ricorda di mettere [Risolto] nel titolo del primo messaggio della discussione.
La vendetta è un piatto da consumare freddo. Per questo hanno inventato il freezer.
Avatar utente
l3on4rdo
Moderatore Globale
Moderatore Globale
 
Messaggi: 9705
Iscrizione: maggio 2008
Località: Roma
Distribuzione: Ubuntu 10.04.4 e 12.04 64bit
Desktop: Gnome

Re: [Bash] Leggere file riga per riga

Messaggioda Laycastle » venerdì 3 febbraio 2012, 13:52

edit anticipato
va bé, diciamo che allora partecipo con un link interessante: http://unix.stackexchange.com/questions ... ssary-cats

ciao :)

p.s. anche secondo me sed o awk potrebbero essere un ottima soluzione.
Ultima modifica di Anonymous il venerdì 3 febbraio 2012, 14:08, modificato 1 volta in totale.
la via più breve tra due punti è l'arabesco.
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1113
Iscrizione: aprile 2011
Località: Torino
Distribuzione: Gentoo ~amd64
Desktop: KDE 4.8

Re: [Bash] Leggere file riga per riga

Messaggioda toro2k » venerdì 3 febbraio 2012, 14:25

l3on4rdo ha scritto:Il motivo è che il primo metodo prevede prima la lettura del file con cat, poi il passaggio dell'output al ciclo while.

No, i processi che compongono la pipeline vengono eseguiti in parallelo, l'output di cat viene scritto sulla pipe nel momento in cui viene prodotto, quindi la shell (tramite read) puo` iniziare a leggere dalla pipe prima che cat sia terminato.
Rispetto alla soluzione con il redirect la soluzione con la pipe e` comunque meno efficiente perche' la shell deve far partire un sotto processo per eseguire cat (col redirect viene eseguito tutto in un processo) e deve inizializzare la pipe (col redirect deve aprire solo un file descriptor). A meno di non dover eseguire lo script a un ritmo forsennato (parecchie volte al secondo, per dire) dal punto di vista dell'efficienza le due soluzioni si (circa) equivalgono.


Laycastle ha scritto:va bé, diciamo che allora partecipo con un link interessante: http://unix.stackexchange.com/questions ... ssary-cats

Interessante, pero` (almeno mi e` parso facendo una prova al volo) non funziona direttamente davanti a while, costringe a definire una funzione che contenga il ciclo.
Software is meant to be soft!
Avatar utente
toro2k
Prode Principiante
 
Messaggi: 24
Iscrizione: gennaio 2012

Re: [Bash] Leggere file riga per riga

Messaggioda l3on4rdo » venerdì 3 febbraio 2012, 14:42

A meno di non dover eseguire lo script a un ritmo forsennato (parecchie volte al secondo, per dire) dal punto di vista dell'efficienza le due soluzioni si (circa) equivalgono.


Crea un file in questo modo:
Codice: Seleziona tutto
l3on4rdo@l3on4rdo-laptop:~/Scrivania$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> outFile = open('filone.txt', 'w')
>>> output = '1 2 3 4 5 6 7 8 9 10'
>>> for i in range(100000):
...     outFile.write(output + '\n')
...
>>> outFile.close()


Poi processalo nei due modi, e ti accorgi che:
Codice: Seleziona tutto
l3on4rdo@l3on4rdo-laptop:~/Scrivania$ time while read line; do echo "ciao" ; done < filone.txt
...
real   0m1.961s
user   0m1.460s
sys   0m0.380s

mentre:
Codice: Seleziona tutto
l3on4rdo@l3on4rdo-laptop:~/Scrivania$ time cat filone.txt | while read line; do echo "ciao" ; done
...
real   0m2.363s
user   0m1.410s
sys   0m0.900s


Dipende tutto da quello che intendi per "circa" :)

edit:
manca un pezzo del mio ragionamento, che aggiungo ora.
Se aumenti di dieci volte il numero di righe del file, ovvero passi da 100000 a 1000000 di righe, la differenza nel tempo di esecuzione dello script non resta costante, ma aumenta.
Codice: Seleziona tutto
l3on4rdo@l3on4rdo-laptop:~/Scrivania$ time while read line; do echo "ciao" ; done < filone2.txt
...
real   0m17.946s
user   0m14.450s
sys   0m3.410s

e
l3on4rdo@l3on4rdo-laptop:~/Scrivania$ time cat filone2.txt | while read line; do echo "ciao" ; done
...
real 0m23.120s
user 0m15.160s
sys 0m7.650s
Ultima modifica di l3on4rdo il venerdì 3 febbraio 2012, 19:14, modificato 1 volta in totale.
Come da regolamento, UNA DISCUSSIONE, PER OGNI PROBLEMA, DOPO aver verificato, con UNA RICERCA, che non sia stato già trattato.
E, prima di sparire con la soluzione, ricorda di mettere [Risolto] nel titolo del primo messaggio della discussione.
La vendetta è un piatto da consumare freddo. Per questo hanno inventato il freezer.
Avatar utente
l3on4rdo
Moderatore Globale
Moderatore Globale
 
Messaggi: 9705
Iscrizione: maggio 2008
Località: Roma
Distribuzione: Ubuntu 10.04.4 e 12.04 64bit
Desktop: Gnome

Re: [Bash] Leggere file riga per riga

Messaggioda mikecesure » venerdì 3 febbraio 2012, 14:43

Grazie a tutti per essere intervenuti!!!

patel ha scritto:se ti rimane difficile capire l'esempio precedente
Codice: Seleziona tutto
while read riga; do
  echo $riga
  p=${riga:0:1} # primo carattere della riga
#  echo $p
  if [ $p == "X" ]; then exit; fi # se la riga inizia per X blocca il ciclo
done < testo # file da leggere




La risposta più esauriente è comunque stata quella di patel !!! (good)
Vorrei solo capire meglio come funziona la lettura carattere per carattere...  ???
mikecesure
Prode Principiante
 
Messaggi: 186
Iscrizione: ottobre 2009

Re: [Bash] Leggere file riga per riga

Messaggioda l3on4rdo » venerdì 3 febbraio 2012, 14:45

Fai prima a dire cosa vuoi fare, piuttosto che arrivarci per approssimazioni successive.
Sicuramente patel è entrato nel dettaglio, ma io opterei per l'uso di sed o awk.
Sia per questioni di lunghezza del codice sia per questioni di "performance"

edit:
per iniziare il viaggio nel fantastico mondo degli array in bash, ti consiglio di vedere qui
Ultima modifica di l3on4rdo il venerdì 3 febbraio 2012, 14:48, modificato 1 volta in totale.
Come da regolamento, UNA DISCUSSIONE, PER OGNI PROBLEMA, DOPO aver verificato, con UNA RICERCA, che non sia stato già trattato.
E, prima di sparire con la soluzione, ricorda di mettere [Risolto] nel titolo del primo messaggio della discussione.
La vendetta è un piatto da consumare freddo. Per questo hanno inventato il freezer.
Avatar utente
l3on4rdo
Moderatore Globale
Moderatore Globale
 
Messaggi: 9705
Iscrizione: maggio 2008
Località: Roma
Distribuzione: Ubuntu 10.04.4 e 12.04 64bit
Desktop: Gnome

Re: [Bash] Leggere file riga per riga

Messaggioda mikecesure » venerdì 3 febbraio 2012, 14:51

Allora devo modificare un file: ci sono dei caratteri che segnalano l'inizio della parte del file da controllare ed altri che indicano la fine.
All'interno di questi identificatori (si tratta di più righe) devo verificare la presenza di certe stringhe e in base all'esistenza di queste inserire o cancellare le righe che le contengono.
mikecesure
Prode Principiante
 
Messaggi: 186
Iscrizione: ottobre 2009

Re: [Bash] Leggere file riga per riga

Messaggioda difesaparcosempione » venerdì 3 febbraio 2012, 14:53

mikecesure ha scritto:Ciao a tutti,
premetto che sono un quasi neofita del linguaggio bash, per questo cerco aiuto  ;D
Comunque, io avrei necessità di leggere un file riga per riga e poi, all'incontro di determinati caratteri, eseguire certe azioni per un certo numero di volte, fino a quando la riga non contiene un altro set di caratteri che bloccano questa sorta di ciclo.

Grazie anticipate  :)

Cmq per avere un esempio e poi un link ad un buon manuale ...
http://www.tldp.org/LDP/abs/html/special-chars.html#EX8
vedi code blocks and i/o redirection
ciao
;)
http://difesasempione.wordpress.com/
http://torino.pro-natura.it/
www.pattomutuosoccorso.org
Avatar utente
difesaparcosempione
Rampante Reduce
Rampante Reduce
 
Messaggi: 5178
Iscrizione: luglio 2006
Località: Torino

Re: [Bash] Leggere file riga per riga

Messaggioda l3on4rdo » venerdì 3 febbraio 2012, 14:58

mikecesure ha scritto:Allora devo modificare un file: ci sono dei caratteri che segnalano l'inizio della parte del file da controllare ed altri che indicano la fine.
All'interno di questi identificatori (si tratta di più righe) devo verificare la presenza di certe stringhe e in base all'esistenza di queste inserire o cancellare le righe che le contengono.

Non ho capito :)
O forse sì  ::)

Tu inizi a leggere il file.
Ad un certo punto trovi "Identificatore di inizio numero 1" e devi iniziare a fare alcune cose, fino a che non trovi "Indicatore di fine numero 2".
Le cose che devi fare consistono nel verificare, per le righe tra "Identificatore di inizio numero 1" e "Indicatore di fine numero 2", se ci sono certe stringhe e se le trovi inserire o cancellare le righe?
Fino a cancellarle ci sto... ma inserirle, se già ci sono?
Come da regolamento, UNA DISCUSSIONE, PER OGNI PROBLEMA, DOPO aver verificato, con UNA RICERCA, che non sia stato già trattato.
E, prima di sparire con la soluzione, ricorda di mettere [Risolto] nel titolo del primo messaggio della discussione.
La vendetta è un piatto da consumare freddo. Per questo hanno inventato il freezer.
Avatar utente
l3on4rdo
Moderatore Globale
Moderatore Globale
 
Messaggi: 9705
Iscrizione: maggio 2008
Località: Roma
Distribuzione: Ubuntu 10.04.4 e 12.04 64bit
Desktop: Gnome

Re: [Bash] Leggere file riga per riga

Messaggioda mikecesure » venerdì 3 febbraio 2012, 15:00

Si ho sbagliato, inserirle se non ci sono, ho erroneamente omesso questa parte, comunque hai capito perfettamente!!
mikecesure
Prode Principiante
 
Messaggi: 186
Iscrizione: ottobre 2009

Re: [Bash] Leggere file riga per riga

Messaggioda Laycastle » venerdì 3 febbraio 2012, 15:03

Se non ci sono dove dovresti inserirle? Potresti fare un esempio concreto?
la via più breve tra due punti è l'arabesco.
Avatar utente
Laycastle
Entusiasta Emergente
Entusiasta Emergente
 
Messaggi: 1113
Iscrizione: aprile 2011
Località: Torino
Distribuzione: Gentoo ~amd64
Desktop: KDE 4.8

Re: [Bash] Leggere file riga per riga

Messaggioda l3on4rdo » venerdì 3 febbraio 2012, 15:04

mikecesure ha scritto:Si ho sbagliato, inserirle se non ci sono, ho erroneamente omesso questa parte, comunque hai capito perfettamente!!

Servirebbe un esempio un pochino più esplicativo
(leggi, posta un estratto di questo file e degli esempi per capire cosa intendi per indicatori)
Come da regolamento, UNA DISCUSSIONE, PER OGNI PROBLEMA, DOPO aver verificato, con UNA RICERCA, che non sia stato già trattato.
E, prima di sparire con la soluzione, ricorda di mettere [Risolto] nel titolo del primo messaggio della discussione.
La vendetta è un piatto da consumare freddo. Per questo hanno inventato il freezer.
Avatar utente
l3on4rdo
Moderatore Globale
Moderatore Globale
 
Messaggi: 9705
Iscrizione: maggio 2008
Località: Roma
Distribuzione: Ubuntu 10.04.4 e 12.04 64bit
Desktop: Gnome

Re: [Bash] Leggere file riga per riga

Messaggioda mikecesure » venerdì 3 febbraio 2012, 15:33

Codice: Seleziona tutto
[:/progetto1]
utente1 = rw
utente2 = rw
utente3 = rw

[:/progetto2]
utente2 = rw
utente4 = rw

Praticamente quando, durante lo scorrimento del file, si incontra la riga con [:/progetto] (nota: il nome del $progetto è dato da una variabile), per tutte le righe successive, fino ad un [:/altroprogetto], ho bisogno di verificare la presenza o meno dell'utente (anche quello dato da una variabile).
I casi sono due:
  - se c'è necessità di cancellarlo, devo verificare la presenza dell'utente e poi eliminare la riga relativa
  - se invece si tratta di un inserimento devo controllare fino al progetto successivo che l'utente non sia già presente e dopodiché inserirlo dopo il nome del progetto da cui parte la verifica.

Capito?? =)
mikecesure
Prode Principiante
 
Messaggi: 186
Iscrizione: ottobre 2009

Re: [Bash] Leggere file riga per riga

Messaggioda patel » venerdì 3 febbraio 2012, 15:47

mikecesure ha scritto:La risposta più esauriente è comunque stata quella di patel !!! (good)
quello che ne sa meno di tutti, visto che mikecesure è ai primi passi come me, cercate di non esagerare con le difficoltà evitando se possibile sed anche a scapito delle performances.
Ultima modifica di patel il venerdì 3 febbraio 2012, 15:50, modificato 1 volta in totale.
Un titolo ben azzeccato attira l'attenzione degli esperti in quel campo, fa risparmiare tempo a voi, aumenta la probabilità di successo.
patel
Accecante Asceta
Accecante Asceta
 
Messaggi: 23729
Iscrizione: aprile 2008
Località: Livorno

Re: [Bash] Leggere file riga per riga

Messaggioda l3on4rdo » venerdì 3 febbraio 2012, 15:55

@ patel
tranquillo, niente sed.
in questo caso credo sia meglio awk  ;D

ps: sto buttando giù un paio di idee. Appena pronte le posto. Ma ho da fare per la tesi  (yes)
Ultima modifica di l3on4rdo il venerdì 3 febbraio 2012, 16:20, modificato 1 volta in totale.
Come da regolamento, UNA DISCUSSIONE, PER OGNI PROBLEMA, DOPO aver verificato, con UNA RICERCA, che non sia stato già trattato.
E, prima di sparire con la soluzione, ricorda di mettere [Risolto] nel titolo del primo messaggio della discussione.
La vendetta è un piatto da consumare freddo. Per questo hanno inventato il freezer.
Avatar utente
l3on4rdo
Moderatore Globale
Moderatore Globale
 
Messaggi: 9705
Iscrizione: maggio 2008
Località: Roma
Distribuzione: Ubuntu 10.04.4 e 12.04 64bit
Desktop: Gnome

Re: [Bash] Leggere file riga per riga

Messaggioda mikecesure » venerdì 3 febbraio 2012, 16:01

aspetteremo trepidanti  ;)
mikecesure
Prode Principiante
 
Messaggi: 186
Iscrizione: ottobre 2009

Successiva

Torna a Programmazione

Chi c’è in linea

Visualizzano questa pagina: Eresia, SuperStep e 1 ospite