[bash] usare awk come wrapper file di testo

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
smtux
Linux 3.x
Linux 3.x
Messaggi: 977
Iscritto il: gio 1 set 2005, 0:00
Slackware: 12.0
Località: somewhere in the time

Re: [bash] usare awk come wrapper file di testo

Messaggio da smtux »

spina ha scritto:
smtux ha scritto:...potreste gentilmente spiegarmi la sintassi che mi avete postato?...
Ma dello script di sed o di awk?

Spina
sed

Avatar utente
d4z_c0nf
Packager
Packager
Messaggi: 1296
Iscritto il: mar 14 mar 2006, 18:07
Nome Cognome: Rocco Aliberti
Slackware: 14.2-current64
Kernel: 4.14.73
Desktop: awesomeWM
Località: Pinerolo

Re: [bash] usare awk come wrapper file di testo

Messaggio da d4z_c0nf »

Offtopic: Scusatemi tutti, in primis smtux, che asserisce di voler usare a tutti i costi (;))awk:

Non è più "semplice" una riga di sed tipo questa:

Codice: Seleziona tutto

ipAddress=`sed -r 's/(ip:\ +)(.)/\2/' file.txt`    
[/offtopic]

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [bash] usare awk come wrapper file di testo

Messaggio da Mario Vanoni »

offtopic

Esiste una terza soluzione:

cut -d ' ' -f 2 file.txt

Avatar utente
d4z_c0nf
Packager
Packager
Messaggi: 1296
Iscritto il: mar 14 mar 2006, 18:07
Nome Cognome: Rocco Aliberti
Slackware: 14.2-current64
Kernel: 4.14.73
Desktop: awesomeWM
Località: Pinerolo

Re: [bash] usare awk come wrapper file di testo

Messaggio da d4z_c0nf »

Mario Vanoni ha scritto:offtopic

Esiste una terza soluzione:

cut -d ' ' -f 2 file.txt
Sì infatti, volevo postarla, ma in questo caso dovremmo essere sicuri che quel file contenga solo quella riga.

rock

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [bash] usare awk come wrapper file di testo

Messaggio da Mario Vanoni »

d4z_c0nf ha scritto:
Mario Vanoni ha scritto:offtopic

Esiste una terza soluzione:

cut -d ' ' -f 2 file.txt
Sì infatti, volevo postarla, ma in questo caso dovremmo essere sicuri che quel file contenga solo quella riga.
time grep '^ip:' file.txt | cut -d ' ' -f 2
0m0.001s

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [bash] usare awk come wrapper file di testo

Messaggio da targzeta »

spina ha scritto:...

Codice: Seleziona tutto

ipAddress=`sed /ip:/'{s/.*ip:\( \)\+//}' file.txt`
Lo script dice a sed:"quando trovi, in una riga, l'espressione regolare 'ip:' allora esegui il primo comando successivo, che in questo caso è racchiuso tra parentesi graffe non necessarie, dato che è anche un solo comando. Il comando è il comando 's' ed i suoi argomenti sono (separati dal carattere '/'):

Codice: Seleziona tutto

.*ip:\( \)\+
il testo che deve sostituire eil testo con cui lo deve sostituire, dato che è vuoto, in pratica si limita a cancellare il testo che deve sostituire.

Quindi in pratica cancella, su ogni riga che contiene la RE 'ip:', tutto quello che matcha il concatenamento di:
  • qualsiasi carattere (.) ripetuto 0 o più volte (*) (questo elimina eventuali caratteri o spazi iniziali prima di 'ip:', che in questo caso non ci sono)
  • ip:
  • uno spazio ripetuto da 1 a più volte (\( \)\+)
E dato che sed, ogni riga, dopo averla elaborata la manda sull'output standard (a meno che non si usi l'opzione '-n'), ecco che in output abbiamo tutto quello che segue 'ip: ' ne file 'file.txt'.

Spina

P.S. Detto questo, sed come ogni programma va prima imparato e poi usato :), per impararlo c'è la pagina di info

Codice: Seleziona tutto

info sed
Lo so che è rognoso, ma una volta imparato non si dimentica più....e lo si usa tantissimo.
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
conraid
Staff
Staff
Messaggi: 13630
Iscritto il: gio 14 lug 2005, 0:00
Nome Cognome: Corrado Franco
Slackware: current64
Desktop: kde
Località: Livorno
Contatta:

Re: [bash] usare awk come wrapper file di testo

Messaggio da conraid »

Mario Vanoni ha scritto:offtopic

Esiste una terza soluzione:

cut -d ' ' -f 2 file.txt
Offtopic: A me restituisce tutta la riga, e non solo l'ip.
Siccome dall'esempio mostrato ci sono più spazi (a meno che non sia un tab) una soluzione con cut (che è la prima che provo in questi casi) non da risultati uniformi, il tutto imho e indipendentemente dal prendere solamente le righe con ip:

Avatar utente
d4z_c0nf
Packager
Packager
Messaggi: 1296
Iscritto il: mar 14 mar 2006, 18:07
Nome Cognome: Rocco Aliberti
Slackware: 14.2-current64
Kernel: 4.14.73
Desktop: awesomeWM
Località: Pinerolo

Re: [bash] usare awk come wrapper file di testo

Messaggio da d4z_c0nf »

Mario Vanoni ha scritto:
d4z_c0nf ha scritto:
Mario Vanoni ha scritto:offtopic

Esiste una terza soluzione:

cut -d ' ' -f 2 file.txt
Sì infatti, volevo postarla, ma in questo caso dovremmo essere sicuri che quel file contenga solo quella riga.
time grep '^ip:' file.txt | cut -d ' ' -f 2
0m0.001s
Offtopic: Mario io avevo provato la versione con -d ':', effettivamente quella con lo spazio mi restuisce come stringa " ", visto che ci sono più spazi. Con ":" mi restituisce, la riga compresi ovviamente gli spazi precedenti all'ip(numero), se invece stampo il risultato dell'espressione con echo, ottengo solo l'ip:

Codice: Seleziona tutto

rock@localhost:~$ cut -d ' ' -f 2 file.txt

rock@localhost:~$ cut -d ' ' -f 2 file.txt

rock@localhost:~$ cut -d ':' -f 2 file.txt
    192.168.1.0
rock@localhost:~$ echo $(cut -d ':' -f 2 file.txt)
192.168.1.0
Avevo pensato ovviamente a grep, però poi per lui diventava ancora più "rogonosa" come soluzione. Avrebbe dovuto poi guardarsi anche il man di grep (che non fa male, visto quanto spesso lo si usa).
Quindi in pratica la soluzione con grep e cut impiega lo stesso tempo di sed o awk.
Buono a sapersi.
rock[/offtopic]

Avatar utente
conraid
Staff
Staff
Messaggi: 13630
Iscritto il: gio 14 lug 2005, 0:00
Nome Cognome: Corrado Franco
Slackware: current64
Desktop: kde
Località: Livorno
Contatta:

Re: [bash] usare awk come wrapper file di testo

Messaggio da conraid »

d4z_c0nf ha scritto: Quindi in pratica la soluzione con grep e cut impiega lo stesso tempo di sed o awk.
[flame-mode]
ma con una riga solamente anche in java o mono ci metterebbe lo stesso tempo :-'
[/flame-mode]

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [bash] usare awk come wrapper file di testo

Messaggio da targzeta »

conraid ha scritto:...
Offtopic: A me restituisce tutta la riga, e non solo l'ip.
Siccome dall'esempio mostrato ci sono più spazi (a meno che non sia un tab) una soluzione con cut (che è la prima che provo in questi casi) non da risultati uniformi, il tutto imho e indipendentemente dal prendere solamente le righe con ip:
Offtopic: Pensa che a me restituisce uno spazio e basta :)
Ecco perchè, generalmente, se si vuole usare cut bisogna sempre metterlo in pipe con tr, ad esempio con:

Codice: Seleziona tutto

cat file.txt | tr -s '[[:blank:]]' '_'| cut -d'_' -f2
facendo attenzione al carattere scelto per tr.

Spina[/offtopic]
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

smtux
Linux 3.x
Linux 3.x
Messaggi: 977
Iscritto il: gio 1 set 2005, 0:00
Slackware: 12.0
Località: somewhere in the time

Re: [bash] usare awk come wrapper file di testo

Messaggio da smtux »

spina ha scritto:
spina ha scritto:...

Codice: Seleziona tutto

ipAddress=`sed /ip:/'{s/.*ip:\( \)\+//}' file.txt`
Lo script dice a sed:"quando trovi, in una riga, l'espressione regolare 'ip:' allora esegui il primo comando successivo, che in questo caso è racchiuso tra parentesi graffe non necessarie, dato che è anche un solo comando. Il comando è il comando 's' ed i suoi argomenti sono (separati dal carattere '/'):

Codice: Seleziona tutto

.*ip:\( \)\+
il testo che deve sostituire eil testo con cui lo deve sostituire, dato che è vuoto, in pratica si limita a cancellare il testo che deve sostituire.

Quindi in pratica cancella, su ogni riga che contiene la RE 'ip:', tutto quello che matcha il concatenamento di:
  • qualsiasi carattere (.) ripetuto 0 o più volte (*) (questo elimina eventuali caratteri o spazi iniziali prima di 'ip:', che in questo caso non ci sono)
  • ip:
  • uno spazio ripetuto da 1 a più volte (\( \)\+)
E dato che sed, ogni riga, dopo averla elaborata la manda sull'output standard (a meno che non si usi l'opzione '-n'), ecco che in output abbiamo tutto quello che segue 'ip: ' ne file 'file.txt'.

Spina

P.S. Detto questo, sed come ogni programma va prima imparato e poi usato :), per impararlo c'è la pagina di info

Codice: Seleziona tutto

info sed
Lo so che è rognoso, ma una volta imparato non si dimentica più....e lo si usa tantissimo.
grazie spina, sicuramente me lo studio.
Voglio anche approfondire awk... visto che spesso ho tra le mani file di log... non si sa mai!

grazie a tutti è venuto fuori un thread interessante.
=D>

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [bash] usare awk come wrapper file di testo

Messaggio da Mario Vanoni »

Se file.txt contiene
ip: 0 o piu` spazi + 0 o piu` tabulatori il_numero_ip
solo awk da sempre il risultato corretto,
informazioni (fields) divise da white spaces.

Scusate, ma awk ha i suoi pregi
Mario

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [bash] usare awk come wrapper file di testo

Messaggio da targzeta »

Mario Vanoni ha scritto:...
solo awk da sempre il risultato corretto,
...
Bhé questo non è proprio vero. Sia lo script di sed di conraid:

Codice: Seleziona tutto

sed /ip:/'{s/.*ip:\s\+//}' file.txt 
sia il mio precedento comando in pipe:

Codice: Seleziona tutto

cat file.txt | tr -s '[[:blank:]]' '_'| cut -d'_' -f2
funzionano bene nel caso che hai citato.

Spina
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [bash] usare awk come wrapper file di testo

Messaggio da Mario Vanoni »

spina ha scritto:
Mario Vanoni ha scritto:...
solo awk da sempre il risultato corretto,
...
Bhé questo non è proprio vero. Sia lo script di sed di conraid:

Codice: Seleziona tutto

sed /ip:/'{s/.*ip:\s\+//}' file.txt 
sia il mio precedento comando in pipe:

Codice: Seleziona tutto

cat file.txt | tr -s '[[:blank:]]' '_'| cut -d'_' -f2
funzionano bene nel caso che hai citato.

Spina
Hai ragione Emanuele.

>20 anni fa, non avendo compilatore C,
programmavo in sh e [n]awk (anche 100+ righe).
Con la macchina lenta si sono finalmente decisi
di comprarmi il compilatore C AT&T +lint e Co.,
GCC non esisteva, >1700 Euro ai tempi.
Tradussi awk in C, grande quadagno di tempo.
Ma per one-liner (occasionali) awk rimane ideale.

smtux
Linux 3.x
Linux 3.x
Messaggi: 977
Iscritto il: gio 1 set 2005, 0:00
Slackware: 12.0
Località: somewhere in the time

Re: [bash] usare awk come wrapper file di testo

Messaggio da smtux »

domanda:
con awk sarebbe possibile riscrivere l'ipaddress nel file di configurazione della lan?
Intendo quel file che viene letto allo startup della rete.

Rispondi