Repository 32bit  Forum
Repository 64bit  Wiki

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.

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » lun set 17, 2012 15:39

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

Emanuele

Uso datetime perchè tenendo nel database degli appuntamenti da svolgere ho anche bisogno dell'orario dell'appuntamento..
Ma questa è solo una "new entry", per le vecchie date importate dal file vcf non sapendo l'orario si
potrebbero inserire tutte per le 12...
Il formato esatto è questo: '2012-05-22 12:00:00' come saprete

Vi ringrazio tantissimo
Francesco :D
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

Re: Aiuto Awk - Grep - Sed

Messaggioda targzeta » lun set 17, 2012 18:00

Ti ho diviso la data in 'gg' 'mm' 'aa' (sono nell'array 'gma'). Occhio che do per scontato che le date siano tutte dal 2000 in poi, dato che c'è solo l'anno nella vcard, io ci ho aggiunto un '20' davanti. Come orario ci ho messo sempre '00:00:00' e ti ho quotato il tutto:
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)
      # info[1] == data, info[2] == id_trattamento, info[3] == id_dipendente
      split(info[1], gma, ".");
      # gma[1] == giorno, gma[2] == mese, gma[3] == anno
      printf "insert into appuntamenti (id_cliente, %s, %s, '20%s-%s-%s 00:00:00')\n",
        info[3], info[2], gma[3], gma[2], gma[1];
    }
}
a me come output da (sull'unica entry che hai messo ad inizio thread):
Codice: Seleziona tutto
insert into clienti (.....) Values (Adele, Xxxxeri)
insert into appuntamenti (id_cliente, 4, 2, '2011-01-22 00:00:00')
insert into appuntamenti (id_cliente, 4, 2, '2011-02-12 00:00:00')
insert into appuntamenti (id_cliente, 4, 2, '2011-03-05 00:00:00')
insert into appuntamenti (id_cliente, 4, 2, '2011-03-26 00:00:00')
insert into appuntamenti (id_cliente, 4, 2, '2011-04-23 00:00:00')
insert into appuntamenti (id_cliente, 4, 2, '2010-11-16 00:00:00')
insert into appuntamenti (id_cliente, 4, 2, '2010-12-09 00:00:00')
insert into appuntamenti (id_cliente, 4, 2, '2010-12-30 00:00:00')

Comunque io ritorno dire che te ne fai poco di queste cose se ti server un'istruzione sql per prelevare l'id del cliente appena inserito.
Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » mar set 18, 2012 2:47

spina ha scritto: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';
.....
Comunque io ritorno dire che te ne fai poco di queste cose se ti server un'istruzione sql per prelevare l'id del cliente appena inserito.
Emanuele

Su tua dritta mi sono visto la funzione LASTE_INSERT_ID() :D
ed ho modificato al volo il tuo script

Ho cambiato provvisoriamente solo l'output da produrre nelle printf così
Codice: Seleziona tutto
printf "insert into clienti values (null, '%s', '%s', 'telefono', null);\n",nome, cognome;
printf "insert into  appuntamenti VALUES  ( null , '20%s-%s-%s 00:00:00', 'descrizionecognomeesempio', LAST_INSERT_ID(), %s );\n", gma[3], gma[2], gma[1], info[3];

L'unico problema e che molte date non vanno perche nel file di origine, il campo NOTE,
al 75esimo carattere và a capo dividendo le date cosi...
Codice: Seleziona tutto
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

Ora provo a mettere il campo NOTE su una sola riga e collegare le stringe togliendo lo spazio della riga successiva
e poi provo ad estrapolare anche il campo telefono e passarlo ad una variabile per il campo cliente..

Conoscete qualche bella guida possibilmente in italiano per awk e sed così da poter provare a risolvere da solo?
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

Re: Aiuto Awk - Grep - Sed

Messaggioda targzeta » mar set 18, 2012 14:27

Ma guarda che questa evenienza l'avevo già sistemata io. Infatti se guardi l'output che ti ho postato prima le date sono corrette.

Però LAST_INSERT_ID ti ritorna l'ultimo id inserito, ciò vuol dire che dopo che avrai inserito un appuntamento, LAST_INSERT_ID ti ritornerà l'id di questo appuntamento e non più del cliente.

Secondo me devi fare tutto via PHP, così ti puoi salvare l'id del cliente in una variabile.
Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » gio set 20, 2012 16:52

spina ha scritto:Secondo me devi fare tutto via PHP, così ti puoi salvare l'id del cliente in una variabile.
Emanuele

L'ho fatto non funziona come dovrebbe :evil:
Per ora mi sono limitato solo ad inserire il cliente e vedere se riuscivo a salvare l'ultimo id aggiunto
Codice: Seleziona tutto
<?php
include("connessione.php");
  $file = fopen("contacts2.vcf", "r" )or die ("Non posso aprire il file");
  while (! feof($file))
  {
    $line=fgets($file, 1024);

    if ( (substr($line,0,2) == "FN") )
    {
      $nome_cognome=substr($line, 3);
      $nome_array = explode(" ", $nome_cognome);
      if ($nome_array[0] == "") $nome_array[0] = "Sconosciuto";
      if ($nome_array[1] == "") $nome_array[1] = "Sconosciuto";   
    }
    if ( substr($line, 0,3) == "TEL")
      $telefono= substr($line,14);

    if (isset($nome_array[0]) && isset($nome_array[1]) && isset($telefono) )
    {
      /*print "INSERT INTO clienti VALUES (NULL, '$nome_array[0]','$nome_array[1]','$telefono', NULL);"; */

      $query=mysql_query("INSERT INTO clienti VALUES (NULL, '$nome_array[0]','$nome_array[1]','$telefono', NULL);");
      if($query == FALSE) print "<BR>Errore nell'inserimento dell'utente: '$nome_array[0]', '$nome_array[1]'";
      else print "<BR>Inserimento dell'utente: '$nome_array[0]', '$nome_array[1]' riuscito";
      $idcliente=mysql_insert_id();
      print "<BR>Ultimo ID cliente inserito = $idcliente";
      unset($nome_array[0]); unset($nome_array[1]); unset($telefono);
    }
   
    /*PARTE DOVE AGGIUNGO I VARI APPUNTAMENTI*/
   /*DA FINIRE*/
      if (substr($line,0,4) == "NOTE")
      {
   $note=substr($line,5);
      }else
   if (substr($line,0,1) == " ") /*CONTINUO DI NOTE*/
   {
     $note2 = substr($line, 0);
   }
   
   if ( isset($note) && isset($note2) )
   {
     trim ($note);trim($note2);
     $notacompleta= $note."".$note2;
     $appuntamenti = explode("\\\"", $notacompleta); //DIVIDO E CICLO PER OGNI APPUNTAMENTO eSEMPIO: 07.08.12-2(9)\"
     for($j=0;$j<count($appuntamenti);$j++)
       {
         $info= explode("-",$appuntamenti[$j]); //DIVIDO APPUNTAMENTO IN DATA - PRESTAZIONE - DIPENDENTE
         $data=$info[0];
         //SEPARO LA DATA
         $divdata = explode(".",$data);
         /* Giorno=$divdata[0] - Mese=$divdata[1] - Anno=$divdata[2]";*/
         //SEPARO DIPENDENTE E PRESTAZIONE
         $dip_pre = explode("(",$info[1]);
         $dipendente=$dip_pre[0];
         $prestazione=substr($dip_pre[1],0,1);
        
         /*AGG CONTROLLO SE DIPENDENTE=[0-9] && PRESTAZIONE=[0-9] && DATA E' ESATTA SCRIVI*/
         echo "<BR>INSERT INTO appuntamenti VALUES  ( null , '$divdata[2]-$divdata[1]-$divdata[0] 00:00:00', 'descrizionecognomeesempio', LAST_INSERT_ID(clienti), $dipendente, $prestazione);\n";

       }
     print "Cliente successivo<BR><BR><BR><BR>";
     unset($note);unset($note2);
   }
   
  }
   
    ?>

Se eseguo la pagina in php mi aggiunge il record così:
Codice: Seleziona tutto
mysql> select * from clienti;
+----+----------+-----------------+--------------+---------------+
| id | nome     | Cognome         | Telefono     | Via           |
+----+----------+-----------------+--------------+---------------+
|  1 | cliente1 | cognomecliente1 | 345435467    | marginesu 20  |
|  2 | cliente2 | cognome2        | 32334444     | vaiiiii       |
| 17 | Adele    | MXXXXX
 | NULL          |84
+----+----------+-----------------+--------------+---------------+
8 rows in set (0.00 sec)

Mentre se invece faccio solo stampare la query, e la eseguo da mysql
i dati vengono inseriti correttamente..

Sapete dirmi il perchè????
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

Re: Aiuto Awk - Grep - Sed

Messaggioda targzeta » gio set 20, 2012 17:27

Probabilmente è sempre lo stesso problema con i caratteri non stampabili di DOS. Devi ripulire la stringa letta dal file per sostituire una serie di caratteri non stampabili con un singolo spazio.

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » gio set 20, 2012 17:32

Mi sapresti dire quale espressione posso usare per indicare qualsiasi carattere non stampabile?????
Grazie ;)
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

Re: Aiuto Awk - Grep - Sed

Messaggioda targzeta » gio set 20, 2012 17:51

Dovrebbe bastare sostituire la riga:
Codice: Seleziona tutto
$line=fgets($file, 1024);
con:
Codice: Seleziona tutto
$line=preg_replace('/[[:space:]]+/', ' ', fgets($file, 1024));

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » gio set 20, 2012 17:58

Ahahahaha Funzionaaaaa!!!!
Ne sai troppo!!!! ;D

E io che mi stavo azzuffando per cambiare il fileformat con vim.... :cry:

Adesso provo ad aggiungere anche gli appuntamenti :D
Se riesco faccio sapere
Grazièèèèèè :D
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » sab set 22, 2012 14:47

Ho un'altra domanda :roll:
Sto leggendo un file in php con fgets.
Mi sapete dire se è possibile leggere la riga successiva a quella in lettura in quel momento???
In pratica leggo il file riga per riga ma prima di leggere la riga attuale vorrei sapere se la riga successiva è di un certo tipo
mi sapete dire se è possibile???

Grazie ;)
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

Re: Aiuto Awk - Grep - Sed

Messaggioda targzeta » sab set 22, 2012 18:08

L'approccio mi sembra sbagliato. Devi fare un'automa a stati finiti. Più o meno l'algoritmo che devi seguire è questo:
Codice: Seleziona tutto
leggi riga
setta_stato
switch(stato)
  FN:...
  NOTE:...
...
dove la routine "setta_stato" si deve preoccupare anche di ripulire la riga letta. In questo modo, se la riga che stai leggendo è il seguito di una precedente, allora setta stato lascerà la variabile 'stato' inalterata e si limiterà a ripulire la riga (ad esempio eliminando gli spazi iniziali).
Spero di essermi spiegato bene, altrimenti, se posti il codice lo guardiamo insieme.

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » dom set 23, 2012 2:42

Giustissimo... così è molto più semplice e più ordinato :D
Questo è come l'ho iniziato a fare, è solo la base,
mancano le vecchie prassi che trasformano la data e eseguono le query
ma rende l'idea... :
Codice: Seleziona tutto
<?php
  $file = fopen("contacts.vcf", "r" )or die ("Non posso aprire il file");
  $stato = 0;
  while (! feof($file))
  {
    $riga=preg_replace('/[[:space:]]+/', ' ', fgets($file, 1024));
    if ( substr($riga,0,2) == "FN")  $stato=1;
    if (substr($riga,0,3) == "TEL" ) $stato=2;
    if ( substr($riga,0,4) == "NOTE") $stato=3;
    if ( substr($riga,0,3) == "END") $stato=4;
    switch($stato)
    {
      case 1:
   $nome_cognome=substr($riga, 3);
   $nome_array = explode(" ", $nome_cognome);
   if ($nome_array[0] == "") $nome_array[0] = "Sconosciuto";
   if ($nome_array[1] == "") $nome_array[1] = "Sconosciuto";
   $stato=0;
   break;
      case 2:
   $telefono= substr($riga,14);
   print "<br><FONT color=BLUE>Utente  '$nome_array[0]','$nome_array[1]','$telefono' </FONT>";
   //unset($nome_array);unset($nome_cognome);unset($telefono);
   $stato=0;
   break;
      case 3:
   if(isset($note)) $note= $note."".$riga;
   else $note=substr($riga,5);
   break;
      case 4:
   $note=str_replace(" ", "", $note);
   print "<br><FONT color=RED>$note</FONT>";
   $stato=0;
   unset($note);
   break;
    }

  }   
?>

Ora funziona alla grande :D
Grazie 1000
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

Re: Aiuto Awk - Grep - Sed

Messaggioda targzeta » dom set 23, 2012 11:13

E' più o meno come l'avevo immaginato io, solo che:
  • nei case non hai bisogno di resettare lo stato, l'idea è che se gli if iniziali identificano un nuovo stato, si cambia, altrimenti si rimane nel vecchio stato (continuazione di riga);
  • negli if iniziali devi anche identificare la continuazione di riga (la riga inizia con uno spazio, nell'esempio che hai postato al primo post);
  • gli if iniziali dovrebbero essere "if, else if". Altrimenti ogni volta fai tutti i controlli, e non serve;
  • prima dello switch devi anche ripulire la riga, questo va fatto negli if. Ad esempio, nel case 1 tu fai:
    Codice: Seleziona tutto
    $nome_cognome=substr($riga, 3);
    per eliminare l'FN:, ma questo va fatto negli if, il case 1 deve solo fare quello che deve fare (prelevare nome e cognome);
Ma perché usi i tag HTML? Se esegui lo script semplicemente con:
Codice: Seleziona tutto
php script.php
non serve un output formattato per un browser.

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Aiuto Awk - Grep - Sed

Messaggioda targzeta » dom set 23, 2012 15:05

Eccoti l'idea che avevo in mente. Ti ho messo dei TODO che non ho fatto (sono dei placeholder per dove immagino debbano essere fatte le cose).
Codice: Seleziona tutto
<?php
$file = fopen('contacts.vcf', 'r' ) or die ('Non posso aprire il file');

// TODO: collegarsi al database

function _reset()
{
  global $stato, $nome, $cognome, $telefono, $note;

  $stato = 0;
  $nome = $cognome = 'Sconosciuto';
  $telefono = $note = '';
}

_reset();
while (! feof($file))
  {
    $riga = preg_replace('/[[:space:]]+/', ' ', fgets($file, 1024));

    if ( substr($riga,0,2) == 'FN' )
      $stato = 1;
    elseif ( substr($riga,0,3) == 'TEL' )
      $stato = 2;
    elseif ( substr($riga,0,4) == 'NOTE' )
      $stato = 3;
    elseif ( substr($riga,0,3) == 'END' )
      $stato = 4;
    elseif ( substr($riga, 0, 1) != ' ')
      continue;

    $riga = trim(preg_replace('/^[^:]*:/', '', $riga));
    switch ( $stato )
      {
      case 1:
        $tmp = explode(' ', $riga);
        $tmp_size = count($tmp);
        if ( $tmp_size == 1 && $tmp[0] != '' )
          $nome = $tmp[0];
        elseif ( $tmp_size > 1 )
          {
            $cognome = array_pop($tmp);
            $nome = implode(' ', $tmp);
          }
        break;
      case 2:
        $telefono .= $riga;
        break;
      case 3:
        $note .= $riga;
        break;
      case 4:
        print 'Nome: ' . $nome . "\n"
          . 'Cognome: ' . $cognome . "\n"
          . 'Telefono: ' . $telefono . "\n"
          . 'Note: ' . $note . "\n\n";

        // TODO: INSERT nel database

        _reset();
        break;
      }
  }

fclose($file);
// TODO: terminare connessione al database
?>
eseguilo come:
Codice: Seleziona tutto
php script.php

Ricorda che l'interprete PHP se incontra una stringa che inizia con i doppi apici (") si mette ad interpretarla perché all'interno potrebbe trovare variabili o caratteri non stampabili. Quindi se devi scrivere una stringa pura, tipo: 'Non posso aprire il file', è meglio se la metti tra apici singoli (').

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6185
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Aiuto Awk - Grep - Sed

Messaggioda darkstaring » lun set 24, 2012 8:22

Si, è molto simile...
Comunque non capisco perchè aggiungere il controllo
Codice: Seleziona tutto
    elseif ( substr($riga, 0, 1) != ' ')
      continue;

Non basta l' "elseif ( substr($riga,0,3) == 'END' )" per trovare la fine delle note ????
darkstaring
Linux 2.4
Linux 2.4
 
Messaggi: 366
Iscritto il: mer ott 13, 2010 12:55
Desktop: xfce
Distribuzione: Kali Linux

PrecedenteProssimo

Torna a Programmazione

Chi c’è in linea

Visitano il forum: Yahoo [Bot] e 0 ospiti