Aiuto Awk - Grep - Sed

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.
Avatar utente
darkstaring
Linux 3.x
Linux 3.x
Messaggi: 657
Iscritto il: mer 13 ott 2010, 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Aiuto Awk - Grep - Sed

Messaggio da darkstaring »

Sera a tutti :)...

Avrei bisogno di estrarre dei dati da un file vcf di questo tipo:

Codice: Seleziona tutto

BEGIN:VCARD
VERSION:3.0
FN:Adele Xxxxeri
N: Xxxxeri;Adele;;;
TEL;TYPE=CELL:3XX 9771XXX
ADR;TYPE=HOME:;;;Sassari;;07100;
BDAY:2010-04-12
NOTE:16.11.10-2(4)\" 09.12.10-2(4)\" 30.12.10-2(4)\" 22.01.11-2(4)\" 12.02.
 11-2(4)\" 05.03.11-2(4)\" 26.03.11-2(4)\" 23.04.11-2(4)\"\n
END:VCARD
In particolare a mè serveno solo i campi FN e NOTE
che ottengo con
grep -e FN -e NOTE -e '^ ' contacts.vcf
Ma dovrei interpretare e scrivere delle regole per ogni nota presente..
Il formato di ogni nota è questo
16.11.10-2(4)
Data gg.mm.aa - trattamento (dipendente)
mentre su FN viene salvato il nome del cliente...
In pratica per ogni cliente vorrei far scrivere delle stringhe in SQL del tipo:
insert into clienti (.....) Values (Nome, cognome);
insert into appuntamenti (id_cliente, id_dipendente, id_trattamento, data )

E' possibile far fare il tutto in modo ciclico e automatico???

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5441
Iscritto il: ven 2 giu 2006, 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da ZeroUno »

Intanto te li ho messi tutti su una riga:

Codice: Seleziona tutto

$ grep -e FN -e NOTE -e '^ ' contacts.vcf|sed '/^FN/s/$/;/'|cut -f2 -d:|while read a;do echo -n $a;done|sed -r -e 's/([0-9])/ \1/' -e 's/"//g' -e 's/n$//'
Adele Xxxxeri; 16.11.10-2(4) 09.12.10-2(4) 30.12.10-2(4) 22.01.11-2(4) 12.02.11-2(4) 05.03.11-2(4) 26.03.11-2(4) 23.04.11-2(4)
Vedi se ti basta per cominciare o se ti serve altro per andare avanti.
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
brg
Linux 3.x
Linux 3.x
Messaggi: 580
Iscritto il: sab 12 mar 2011, 14:20
Slackware: 15.0
Kernel: 5.15.117
Desktop: KDE5
Località: Montecatini
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da brg »

Ma creare uno script perl non sarebbe più semplice?

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6631
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: Aiuto Awk - Grep - Sed

Messaggio da targzeta »

Questo script per awk:

Codice: Seleziona tutto

/FN:/{
  sub(/FN:/, "", $1);

  nome=$1;
  for ( i=2; i < NF; i++ )
    nome=nome " " $i;
  cognome=$NF;

  printf "insert into clienti (.....) Values (%s, %s)\n", nome, cognome;
}

/NOTE:/{
  sub(/NOTE:/, " ", $0);

  do
    {
      if ( match($0, /^ /) == 0 )
        break;
      sub(/^ */, "", $0);
      note=note $0;
      getline;
    }
  while ( 1 );

  sub(/\\n/, "", note);
  gsub(/\\\" */, " ", note);

  split(note, appuntamenti, " ");
  for ( a in appuntamenti )
    {
      match(appuntamenti[a], /^([^-]*)-([^\(]*)\(([^\)]*)\).*$/, info)
      printf "insert into appuntamenti (id_cliente, %s, %s, %s)\n", info[3], info[2], info[1];
    }
}
a me produce (va lanciato con 'awk -f script file'):

Codice: Seleziona tutto

insert into clienti (.....) Values (Adele, Xxxxeri)
insert into appuntamenti (id_cliente, 4, 2, 22.01.11)
insert into appuntamenti (id_cliente, 4, 2, 12.02.11)
insert into appuntamenti (id_cliente, 4, 2, 05.03.11)
insert into appuntamenti (id_cliente, 4, 2, 26.03.11)
insert into appuntamenti (id_cliente, 4, 2, 23.04.11)
insert into appuntamenti (id_cliente, 4, 2, 16.11.10)
insert into appuntamenti (id_cliente, 4, 2, 09.12.10)
insert into appuntamenti (id_cliente, 4, 2, 30.12.10)
quindi alcune note:
  • probabilmente i valori vanno quotati nella query sql;
  • il formato della data va modificato se il campo del database è di tipo 'date';
  • l'id del cliente lo devi prelevare attraverso una query che però dipende dal DBMS su cui stai lavorando. Ad esempio, MySQL mette a disposizione il metodo LASTE_INSERT_ID() che dovresti eseguire dopo la insert in 'clienti';
Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
darkstaring
Linux 3.x
Linux 3.x
Messaggi: 657
Iscritto il: mer 13 ott 2010, 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da darkstaring »

Grazie a tuttiii ragazzii :)..
Ora provo e vi faccio sapere

Grazieee ;)

Avatar utente
darkstaring
Linux 3.x
Linux 3.x
Messaggi: 657
Iscritto il: mer 13 ott 2010, 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da darkstaring »

A mè sembrerebbe non funzionare.. Forse perchè il mio contacts.vcf è più corposo

Se eseguo

grep -e FN -e NOTE -e '^ ' contacts.vcf|sed '/^FN/s/$/;/'|cut -f2 -d:|while read a;do echo -n $a;done|sed -r -e 's/([0-9])/ \1/' -e 's/"//g' -e 's/n$//'

il terminale non mi resituisce niente ma "mi scrive" [ 8.12-2(8)12.2 ecc ecc] nella shell dove inserisco i comandi ..

Mentre invece con lo script di spina non mi scrive sul file che ho creato..
In pratica ho copiato lo script in scriptspina e creato un nuovo file test.txt
Così ho lanciato
awk -f scriptspina test.txt
Ma dentro test.txt non cè niente...

Potrebbe essere perchè il mio file ha più "record" ?

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6631
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: Aiuto Awk - Grep - Sed

Messaggio da targzeta »

Ma, in realtà il mio script lo devi invocare sul file contacts.vcf. Sarebbe:

Codice: Seleziona tutto

awk -f scriptspina contacts.vcf
poi lui manda tutto quello che produce su stdout.

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

Avatar utente
darkstaring
Linux 3.x
Linux 3.x
Messaggi: 657
Iscritto il: mer 13 ott 2010, 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da darkstaring »

Grazie Emanuele
Efficentissimo e difficilissimo script..
Così funziona.. anche se su alcune stringhe mi aggiunge " ^M "
per esempio

insert into appuntamenti (id_cliente, 1, 2, 02.03.1^M2)

Posso eliminare ovviare questo problema???

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6631
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: Aiuto Awk - Grep - Sed

Messaggio da targzeta »

Il problema, oltre a quelli che ho scritto due post fa, è che non sapendo di preciso il formato esatto del file io mi sono basato sul pezzo che hai postato tu. Dovresti identificare la riga in questione e capire come mai ti mette quel '^M', che sembra tanto un carattere non stampabile in stile DOS.

Però ripeto, dipende quello che ne devi fare, se vuoi inserire tutti questi dati in un database, allora ti conviene scrivere uno script PHP o in un altro linguaggio che ti pemette direttamente l'accesso al DBMS.

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

Avatar utente
darkstaring
Linux 3.x
Linux 3.x
Messaggi: 657
Iscritto il: mer 13 ott 2010, 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da darkstaring »

Guarda l'output che mi viene restituito

Codice: Seleziona tutto

root@:COMPITO$ head -n 50 temp 
)nsert into clienti (.....) Values (Adele, MilXXX
insert into appuntamenti (id_cliente, 4, 2, 22.01.11)
11)ert into appuntamenti (id_cliente, 4, 2, 12.02.
insert into appuntamenti (id_cliente, 4, 2, 05.03.11)
insert into appuntamenti (id_cliente, 4, 2, 26.03.11)
insert into appuntamenti (id_cliente, 4, 2, 23.04.11)
insert into appuntamenti (id_cliente, , , )
insert into appuntamenti (id_cliente, 4, 2, 16.11.10)
insert into appuntamenti (id_cliente, 4, 2, 09.12.10)
insert into appuntamenti (id_cliente, 4, 2, 30.12.10)
)nsert into clienti (.....) Values (Adele, SXXX
insert into appuntamenti (id_cliente, 1, 2, 12.11.10)
insert into appuntamenti (id_cliente, 1, 2, 01.12.10)
insert into appuntamenti (id_cliente, 1, 2, 19.12.10)
11)ert into appuntamenti (id_cliente, 1, 2, 04.01.
insert into appuntamenti (id_cliente, 1, 2, 24.01.11)
insert into appuntamenti (id_cliente, 1, 2, 11.02.11)
insert into appuntamenti (id_cliente, 1, 2, 28.02.11)
insert into appuntamenti (id_cliente, 1, 2, 28.02.11)
insert into appuntamenti (id_cliente, 1, 2, 15.03.11)
insert into appuntamenti (id_cliente, 1, 2, 15.03.11)
01.04.11)to appuntamenti (id_cliente, 1, 2, 
insert into appuntamenti (id_cliente, 1, 2, 01.04.11)
insert into appuntamenti (id_cliente, 1, 3, 15.04.11)
insert into appuntamenti (id_cliente, 1, 2, 09.01.12)
insert into appuntamenti (id_cliente, 1, 2, 27.01.12)
insert into appuntamenti (id_cliente, 1, 2, 14.02.12)
2)sert into appuntamenti (id_cliente, 1, 2, 02.03.1
insert into appuntamenti (id_cliente, 1, 2, 20.03.12)
insert into appuntamenti (id_cliente, 1, 2, 06.04.12)
insert into appuntamenti (id_cliente, 1, 2, 24.04.12)
insert into appuntamenti (id_cliente, 4, 2, 16.11.10)
insert into appuntamenti (id_cliente, 4, 2, 09.12.10)
insert into appuntamenti (id_cliente, 4, 2, 30.12.10)
insert into appuntamenti (id_cliente, 4, 2, 22.01.11)
11)ert into appuntamenti (id_cliente, 4, 2, 12.02.
insert into appuntamenti (id_cliente, 4, 2, 05.03.11)
insert into appuntamenti (id_cliente, 4, 2, 26.03.11)
insert into appuntamenti (id_cliente, 4, 2, 23.04.11)
26.10.10)to appuntamenti (id_cliente, 1, 2, 
insert into appuntamenti (id_cliente, 1, 2, 19.04.11)
insert into appuntamenti (id_cliente, 1, 2, 06.05.11)
2, 20.05.11)appuntamenti (id_cliente, 1, 
insert into appuntamenti (id_cliente, 1, 2, 07.06.11)
insert into appuntamenti (id_cliente, 1, 2, 28.06.11)
insert into appuntamenti (id_cliente, 1, 2, 15.07.11)
insert into appuntamenti (id_cliente, 1, 2, 03.08.11)
insert into appuntamenti (id_cliente, 4, 2, 11.05.12)
12.11) into appuntamenti (id_cliente, 1, 2, 20.
5.06.12)nto appuntamenti (id_cliente, 1, 2, 0

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6631
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: Aiuto Awk - Grep - Sed

Messaggio da targzeta »

Sì sembrerebbero proprio dei caratteri non stampabili che sballano l'output. Però se non ti sbilanci è difficile aiutarti. Prova con questo:

Codice: Seleziona tutto

/FN:/{
  gsub(/[[:space:]]+/, " ", $0);
  sub(/FN:/, "", $1);

  nome=$1;
  for ( i=2; i < NF; i++ )
    nome=nome " " $i;
  cognome=$NF;

  printf "insert into clienti (.....) Values (%s, %s)\n", nome, cognome;
}

/NOTE:/{
  sub(/NOTE:/, " ", $0);

  do
    {
      if ( match($0, /^ /) == 0 )
        break;
      sub(/^ */, "", $0);
      note=note $0;
      getline;
    }
  while ( 1 );

  gsub(/[[:space:]]+/, " ", note);
  sub(/\\n/, "", note);
  gsub(/\\\" */, " ", note);

  split(note, appuntamenti, " ");
  for ( a in appuntamenti )
    {
      match(appuntamenti[a], /^([^-]*)-([^\(]*)\(([^\)]*)\).*$/, info)
      printf "insert into appuntamenti (id_cliente, %s, %s, %s)\n", info[3], info[2], info[1];
    }
}
Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
ZeroUno
Staff
Staff
Messaggi: 5441
Iscritto il: ven 2 giu 2006, 14:52
Nome Cognome: Matteo Rossini
Slackware: current
Kernel: slack-current
Desktop: ktown-latest
Distribuzione: 01000000-current
Località: Roma / Castelli
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da ZeroUno »

spina ha scritto:la riga in questione e capire come mai ti mette quel '^M', che sembra tanto un carattere non stampabile in stile DOS.
I contacts.vcf sono creati da windows di solito :)
Packages finder: slakfinder.org | Slackpkg+, per aggiungere repository a slackpkg

Codice: Seleziona tutto

1011010 1100101 1110010 1101111 - 0100000 - 1010101 1101110 1101111

Avatar utente
darkstaring
Linux 3.x
Linux 3.x
Messaggi: 657
Iscritto il: mer 13 ott 2010, 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da darkstaring »

In pratica sto esportando contatti google, ho anche un file csv diviso in campi separati da "," così:

Codice: Seleziona tutto

First Name,Middle Name,Last Name,Title,Suffix,Initials,Web Page,Gender,Birthday,Anniversary,Location,Language,Internet Free Busy,Notes,E-mail Address,E-mail 2 Address,E-mail 3 Address,Primary Phone,Home Phone,Home Phone 2,Mobile Phone,Pager,Home Fax,Home Address,Home Street,Home Street 2,Home Street 3,Home Address PO Box,Home City,Home State,Home Postal Code,Home Country,Spouse,Children,Manager's Name,Assistant's Name,Referred By,Company Main Phone,Business Phone,Business Phone 2,Business Fax,Assistant's Phone,Company,Job Title,Department,Office Location,Organizational ID Number,Profession,Account,Business Address,Business Street,Business Street 2,Business Street 3,Business Address PO Box,Business City,Business State,Business Postal Code,Business Country,Other Phone,Other Fax,Other Address,Other Street,Other Street 2,Other Street 3,Other Address PO Box,Other City,Other State,Other Postal Code,Other Country,Callback,Car Phone,ISDN,Radio Phone,TTY/TDD Phone,Telex,User 1,User 2,User 3,User 4,Keywords,Mileage,Hobby,Billing Information,Directory Server,Sensitivity,Priority,Private,Categories
Riesco + o meno a vedere i campi che mi servono con
cat contacts.csv | awk -F"," '{ print $1 $2 $3 $4 $14}'
ma avvolte i dati si ripetono come in first name e middle name, avvolte ne manca uno o un'altro..

Avatar utente
darkstaring
Linux 3.x
Linux 3.x
Messaggi: 657
Iscritto il: mer 13 ott 2010, 13:55
Nome Cognome: Francesco Achenza
Desktop: KDE
Distribuzione: Arch Linux
Contatta:

Re: Aiuto Awk - Grep - Sed

Messaggio da darkstaring »

spina ha scritto:Sì sembrerebbero proprio dei caratteri non stampabili che sballano l'output. Però se non ti sbilanci è difficile aiutarti. Prova con questo:

Codice: Seleziona tutto

/FN:/{
  gsub(/[[:space:]]+/, " ", $0);
  sub(/FN:/, "", $1);

  nome=$1;
  for ( i=2; i < NF; i++ )
    nome=nome " " $i;
  cognome=$NF;

  printf "insert into clienti (.....) Values (%s, %s)\n", nome, cognome;
}

/NOTE:/{
  sub(/NOTE:/, " ", $0);

  do
    {
      if ( match($0, /^ /) == 0 )
        break;
      sub(/^ */, "", $0);
      note=note $0;
      getline;
    }
  while ( 1 );

  gsub(/[[:space:]]+/, " ", note);
  sub(/\\n/, "", note);
  gsub(/\\\" */, " ", note);

  split(note, appuntamenti, " ");
  for ( a in appuntamenti )
    {
      match(appuntamenti[a], /^([^-]*)-([^\(]*)\(([^\)]*)\).*$/, info)
      printf "insert into appuntamenti (id_cliente, %s, %s, %s)\n", info[3], info[2], info[1];
    }
}
quindi alcune note:
  • probabilmente i valori vanno quotati nella query sql;
  • il formato della data va modificato se il campo del database è di tipo 'date';
  • l'id del cliente lo devi prelevare attraverso una query che però dipende dal DBMS su cui stai lavorando. Ad esempio, MySQL mette a disposizione il metodo LASTE_INSERT_ID() che dovresti eseguire dopo la insert in 'clienti';
Solo adesso ho visto la seconda relase!
Questo funziona alla grande, restituisce l'output alla perfezione
solo che come pensavi devo modificare la data in un'altro tipo
..io ho usato datetime

Potresti aiutarmi?

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6631
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: Aiuto Awk - Grep - Sed

Messaggio da targzeta »

Ma mi dovresti dire il formato, esatto. Ma perché, datetime(?) non va bene?

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

Rispondi