IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[CSV] probleme pour convertir un fichier texte en requete sql


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 14
    Par défaut [CSV] probleme pour convertir un fichier texte en requete sql
    Salut,

    afin de pouvoir faire un import d'un fichier texte dans une table mysql, j'ai besoin de convertir un fichier en csv/requete sql.Je vous mets 2 lignes de ce fichier:

    id=firewall time="2006-07-02 23:59:28" fw="xxx" tz=+0000 startime="2006-07-02 23:57:28" pri=5 slotlevel=2 ruleid=1 srcif="Ethernet1" srcifname="in" ipproto=udp proto=snmp src=10.10.10.10 srcport=2419 dst=10.10.10.10 dstport=161 dstportname=snmp sent=44 rcvd=95 duration=0.00 logtype="connection"

    id=firewall time="2006-07-02 22:32:59" fw="xxx" tz=+0000 startime="2006-07-02 22:30:59" pri=5 slotlevel=2 ruleid=14 srcif="Ethernet0" srcifname="out" ipproto=udp dstif="Ethernet1" dstifname="in" proto=snmp src=10.10.10.10 srcport=2420 dst=10.10.10.10 dstport=161 dstportname=snmp dstname=net_printers sent=43 rcvd=53 duration=0.00 logtype="connection"

    j'ai 2 problemes:
    1) les champs ne sont pas au format csv: j'ai un nom_du_champ=une valeure, avec parfois des "".
    J'ai déjà essayé de faire un script php qui vire les 'nom_du_champ=', mais j'ai un autre probleme:
    2) d'une ligne à l'autre le nombre de champs n'est pas le meme: 20 pour la premiere ligne, 23 pour la seconde.

    pour retomber sur un fichier csv normal, j'ai essayé avec fgetcsv, mais je bloque avec le probleme numéro 2.
    J'ai ensuite essayé avec fscanf, mais c'est tres complexe, surtout à cause du probleme 2

    Pour éviter ca, j'ai essayé (en vain), de faire un script qui me genere une requete sql en fonction du nombre de champ (ex: time=), et me permettant d'avoir un truc du genre:
    $query="INSERT INTO `matable` SET `time`="xxx", etc...";
    la problématique étant que le script doit pouvoir fonctioner sans tenir compte du nombre de champs, sachant que j'aurais une table sql avec le plus de champs possible.

    si vous avez une piste.
    Merci pour votre aide!

  2. #2
    Membre éprouvé
    Inscrit en
    Janvier 2006
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 140
    Par défaut
    une ligne de ton fichier correspond toujours à une ligne dans ta table sql ?

    si c'est le cas :

    - tu fais un file() pour charger ton fichier sous forme de tableau
    - tu exécutes ton script pour virer les "champ="
    - tu fais un explode() sur les espaces
    - tu comptes le nombre maximal d'élement dans chacune des lignes
    - tu définis ta requête de base par rapport à ce nombre max, en mettant automatiquement à vide tous les derniers champs manquants (si nbchamp > nbchampmax).

    Par contre ça marche seulement si tous les champs sont toujours dans le même ordre et si les champs manquants sont toujours A LA FIN de la ligne, c'est à dire qu'il n'en manque pas au milieu...

  3. #3
    Membre éprouvé
    Inscrit en
    Janvier 2006
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 140
    Par défaut
    zut, je viens de voir qu'en fait ce n'était pas le cas... bon et bien dans ce cas il va falloir que tu fasses une extraction de tous les noms de champs (pas juste les enlever) et regarder dans chaque ligne si cette valeur est donnée...

  4. #4
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    c'est pas tres tres dur... le tout est d'avancer pas a pas.

    * Tu as un enregistrement par ligne (avec une ligne sautée eventuellement ?)
    * Chaque couple champ/valeur est séparé par un espace
    * Certaines valeurs (et toujours celles qui contiennent des espaces) sont entourées de guillemets
    * Le nom des champs et les valeurs sont séparés par =

    donc tu peux t'en sortir avec des expressions regulieres pour recuperer les différents champs (ou un traitement classique de chaine, mais c'est un peu plus chiant)

    et apres generer les requetes qui vont bien avec
    INSERT INTO table (champ1, champ2, champ3) VALUES ('valeur1','valeur2', 'valeur3)

    (et pas INSERT ... SET champ=valeur... ca ca n'existe pas...)

  5. #5
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    Pour l'expression reguliere, essaye qqchose dans ce gout la ;o))

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_match_all('# ([^"= ]+)=(")?((?(2)[^"]+|[^ ]+))(?(2)"| )#U', " $ligne ", $tableau)
    A noter que pour que ca marche, il faut l'appliquer sur chaque LIGNE (ca recupere un tableau avec la 1ere case qui contient le nom du champ et la 3eme case qui contient la valeur du champ)

    L'ajout des espaces au debut et a la fin de $ligne est important

  6. #6
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 14
    Par défaut
    waouw!
    je m'en vais tester ca!
    n'etant pas un kador en regex, j'allais justement te demander quelle genre d'expression reguliere utiliser
    merci bcp de m'avoir consacré un peu de ton temps!

  7. #7
    Membre averti
    Inscrit en
    Juillet 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 14
    Par défaut
    voila mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    $row = 1;
    $handle = fopen("connection_2006_184.log", "r");
    while (($data = fgets($handle, 4096)) !== FALSE) {
     
       preg_match_all('# ([^"= ]+)=(")?((?(2)[^"]+|[^ ]+))(?(2)"| )#U', " $data ", $tableau);
     
       print_r($tableau);
     
       sleep(1);
    }
    fclose($handle);
    ?>
    voila le résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    Array
    (
        [0] => Array
            (
                [0] =>  id=firewall
                [1] =>  fw="xxx"
                [2] =>  startime="2006-07-02
                [3] =>  pri=5
                [4] =>  ruleid=1
                [5] =>  srcifname="in"
                [6] =>  proto=snmp
                [7] =>  srcport=2414
                [8] =>  dstport=161
                [9] =>  sent=44
                [10] =>  duration=0.00
            )
     
        [1] => Array
            (
                [0] => id
                [1] => fw
                [2] => startime
                [3] => pri
                [4] => ruleid
                [5] => srcifname
                [6] => proto
                [7] => srcport
                [8] => dstport
                [9] => sent
                [10] => duration
            )
     
        [2] => Array
            (
                [0] =>
                [1] =>
                [2] =>
                [3] =>
                [4] =>
                [5] =>
                [6] =>
                [7] =>
                [8] =>
                [9] =>
                [10] =>
            )
     
        [3] => Array
            (
                [0] => firewall
                [1] => "xxx"
                [2] => "2006-07-02
                [3] => 5
                [4] => 1
                [5] => "in"
                [6] => snmp
                [7] => 2414
                [8] => 161
                [9] => 44
                [10] => 0.00
            )
     
    )
    je vais essayer de comprendre la regex afin d'obtenir:
    [0] => id
    [1] => time
    [2] => fw
    [3] => tz
    [4] => startime
    [5] => pri
    [6] => slotlevel
    [7] => ruleid
    [8] => srcif
    [9] => srcifname
    [10] => ipproto
    [11] => proto
    [12] => src
    [13] => srcport
    [14] => dst
    [15] => dstport
    [16] => dstportname
    [17] => sent
    [18] => rcvd
    [19] => duration
    [20] => log_type

    à mon avis le probleme vient de la:
    [2] => startime="2006-07-02
    quand on a un espace entre guillemets.

    Merci encore!

  8. #8
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    essaye de remplacer
    par

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [CSV] convertir un fichier texte formaté en CSV
    Par cotede2 dans le forum Langage
    Réponses: 1
    Dernier message: 20/06/2009, 18h08
  2. Comment faire pour convertir des fichiers csv en série ?
    Par Debutante-Excel dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 31/05/2009, 21h34
  3. Convertir un fichier texte du format csv au format hws
    Par slayer23 dans le forum MATLAB
    Réponses: 8
    Dernier message: 14/06/2007, 17h48
  4. Probleme pour effacer un fichier texte (DeleteFile)
    Par nopnop dans le forum Delphi
    Réponses: 10
    Dernier message: 18/06/2006, 23h47
  5. [VBA-E] Macro pour convertir un fichier texte en excel
    Par Nicolas67 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 15/05/2006, 14h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo