Pagina 2 di 3
Re: Aiuto Awk - Grep - Sed
Inviato: lun 17 set 2012, 16:39
da darkstaring
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
Re: Aiuto Awk - Grep - Sed
Inviato: lun 17 set 2012, 19:00
da targzeta
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
Re: Aiuto Awk - Grep - Sed
Inviato: mar 18 set 2012, 3:47
da darkstaring
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()
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?
Re: Aiuto Awk - Grep - Sed
Inviato: mar 18 set 2012, 15:27
da targzeta
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
Re: Aiuto Awk - Grep - Sed
Inviato: gio 20 set 2012, 17:52
da darkstaring
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
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è????
Re: Aiuto Awk - Grep - Sed
Inviato: gio 20 set 2012, 18:27
da targzeta
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
Re: Aiuto Awk - Grep - Sed
Inviato: gio 20 set 2012, 18:32
da darkstaring
Mi sapresti dire quale espressione posso usare per indicare qualsiasi carattere non stampabile?????
Grazie
Re: Aiuto Awk - Grep - Sed
Inviato: gio 20 set 2012, 18:51
da targzeta
Dovrebbe bastare sostituire la riga:
con:
Codice: Seleziona tutto
$line=preg_replace('/[[:space:]]+/', ' ', fgets($file, 1024));
Emanuele
Re: Aiuto Awk - Grep - Sed
Inviato: gio 20 set 2012, 18:58
da darkstaring
Ahahahaha Funzionaaaaa!!!!
Ne sai troppo!!!! ;D
E io che mi stavo azzuffando per cambiare il fileformat con vim....
Adesso provo ad aggiungere anche gli appuntamenti
Se riesco faccio sapere
Grazièèèèèè
Re: Aiuto Awk - Grep - Sed
Inviato: sab 22 set 2012, 15:47
da darkstaring
Ho un'altra domanda
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
Re: Aiuto Awk - Grep - Sed
Inviato: sab 22 set 2012, 19:08
da targzeta
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
Re: Aiuto Awk - Grep - Sed
Inviato: dom 23 set 2012, 3:42
da darkstaring
Giustissimo... così è molto più semplice e più ordinato
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
Grazie 1000
Re: Aiuto Awk - Grep - Sed
Inviato: dom 23 set 2012, 12:13
da targzeta
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: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:
non serve un output formattato per un browser.
Emanuele
Re: Aiuto Awk - Grep - Sed
Inviato: dom 23 set 2012, 16:05
da targzeta
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:
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
Re: Aiuto Awk - Grep - Sed
Inviato: lun 24 set 2012, 9:22
da darkstaring
Si, è molto simile...
Comunque non capisco perchè aggiungere il controllo
Non basta l' "elseif ( substr($riga,0,3) == 'END' )" per trovare la fine delle note ????