Page 1 sur 1

exploitation fichier csv

Posté : 21 juil. 2014, 09:36
par ruben06
Salut a tous,

Je souhaite remplacer certaines valeurs dans un fichier CSV pour en créer un nouveau avec les valeurs remplacées.
Mon souci se trouve dans la mise en forme, je n'arrive pas avec fputcsv a remette chaque cellule a sa place vu qu'elles se mettent les une sous les autres sur la même colonne.
Voici mon code :

if (($handle = fopen("STRAX2014.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 10000, ";")) !== FALSE) {
        $num = count($data);
        for ($c = 0; $c < $num; $c++) {
            if ($data[$c] == "AEGIS") {
                $data[$c] = "Aegis";
            }
            echo $data[$c] . "<br />\n";
        }
        $fp = fopen("new.csv", "a");
        foreach ($data as $fields) {
            $val = explode(";",$fields);
            fputcsv($fp, $val);
        }
    }
    fclose($handle);
}

Merci à tous de votre aide!

Re: exploitation fichier csv

Posté : 21 juil. 2014, 09:52
par sirakawa
Bjr,
Tu as juste un mot à remplacer par un autre? ou ce que tu montres n'est qu'un exemple.

Re: exploitation fichier csv

Posté : 21 juil. 2014, 09:54
par ruben06
Non ce n'est qu'un exemple j'ai pas mal de retouches a faire...

Re: exploitation fichier csv

Posté : 21 juil. 2014, 11:15
par moogli
salut,

le plus simple c'est d'utiliser la fonction file (attention a la taille du fichier quand même).
dans ce cas un simple remplace sur la ligne (bien sur un faut faire attention au séparateur de champ et sauf de ligne) suffit.

pour mettre le contenu du tableau dans le fichier file_put_contents + implode

sinon pour ton code :
- tu ouvre le fichier destination à chaque ligne d'origine sans fermer ça doit pas être jolie en mémoire, voir même cela peux apporter des conflit (qui te posent peux ête problème ici.
tu n'ajoute pas de saut de saut
il faut ouvrir la ressource pour le fichier source, ouvrir celle du fichier cible et ensuite les utiliser.

je ferais quelque chose dans ce goût la
<?php
define('DEBUG', true);
$cible = fopen('fichiercible.csv', 'a');
flock($cible, LOCK_EX);
if (($source = fopen("STRAX2014.csv", "r")) !== false) {
    while (($data = fgetcsv($source, 10000, ";")) !== false) {
        $final = [];
        foreach ($data as $i => $value) {
            if ($value == "AEGIS") {
                $final[$i] = "Aegis";
            }else {
                $final[$i] = $value;
            }
            // histoire de pas polluer l'affichage si pas besoin
            if (DEBUG) {
                echo $data[$i] . "<br />\n";
            }
        }
        // insertion dans le nouveau fichier
        fputcsv($fp, $final);
    }
    fclose($source);
}

flock($cible, LOCK_UN);
fclose($cible);
 
Après il faut voir la taille des fichiers qui seront traité parce que je pense que l'on peux faire beaucoup plus simple
<?php
$source = 'STRAX2014.csv';
$cible = 'lefichierfinal.csv';
$content = file_get_contents($source);

$tabPattern = ['AEGIS', 'AUTRE', 'CHOSE'];
$tabreplace = ['Aegis', 'Autre', 'Chose'];

$withReplace = str_replace($tabPattern, $tabreplace, $content);

file_put_contents($cible, $withReplace);
je te laisse regarder la doc des fonctions utilisées afin de comprendre ce qui est fait.

@+

Re: exploitation fichier csv

Posté : 21 juil. 2014, 11:31
par sirakawa
Bjr
Il faut ouvrir le fichier new.csv en écriture en même temps que l'autre en lecture.
Tu crées un tableau des mots à remplacer un tableau des remplaçants.
boucle
Tu parcours le fichier original comme tu fais (cad ligne par ligne) en créant à chaque fois un tableau nouvelle_ligne.
Tu remplis ce tableau en appliquans str_replace à la ligne d'origine.
Tu copies cette ligne par fputcsv
boucle

Re: exploitation fichier csv

Posté : 21 juil. 2014, 11:48
par ruben06
salut,

le plus simple c'est d'utiliser la fonction file (attention a la taille du fichier quand même).
dans ce cas un simple remplace sur la ligne (bien sur un faut faire attention au séparateur de champ et sauf de ligne) suffit.

pour mettre le contenu du tableau dans le fichier file_put_contents + implode

sinon pour ton code :
- tu ouvre le fichier destination à chaque ligne d'origine sans fermer ça doit pas être jolie en mémoire, voir même cela peux apporter des conflit (qui te posent peux ête problème ici.
tu n'ajoute pas de saut de saut
il faut ouvrir la ressource pour le fichier source, ouvrir celle du fichier cible et ensuite les utiliser.

je ferais quelque chose dans ce goût la
<?php
define('DEBUG', true);
$cible = fopen('fichiercible.csv', 'a');
flock($cible, LOCK_EX);
if (($source = fopen("STRAX2014.csv", "r")) !== false) {
    while (($data = fgetcsv($source, 10000, ";")) !== false) {
        $final = [];
        foreach ($data as $i => $value) {
            if ($value == "AEGIS") {
                $final[$i] = "Aegis";
            }else {
                $final[$i] = $value;
            }
            // histoire de pas polluer l'affichage si pas besoin
            if (DEBUG) {
                echo $data[$i] . "<br />\n";
            }
        }
        // insertion dans le nouveau fichier
        fputcsv($fp, $final);
    }
    fclose($source);
}

flock($cible, LOCK_UN);
fclose($cible);
 
Après il faut voir la taille des fichiers qui seront traité parce que je pense que l'on peux faire beaucoup plus simple
<?php
$source = 'STRAX2014.csv';
$cible = 'lefichierfinal.csv';
$content = file_get_contents($source);

$tabPattern = ['AEGIS', 'AUTRE', 'CHOSE'];
$tabreplace = ['Aegis', 'Autre', 'Chose'];

$withReplace = str_replace($tabPattern, $tabreplace, $content);

file_put_contents($cible, $withReplace);
je te laisse regarder la doc des fonctions utilisées afin de comprendre ce qui est fait.

@+

Merci, ton deuxième code marche nickel :D je vais en effet fouillé la doc pour voir comment ça marche précisément.

Re: exploitation fichier csv

Posté : 21 juil. 2014, 11:58
par ruben
Autre question,

pensez vous qu'il soit possible d'établir une règle précisant que si je trouve tel mot dans une cellule, je remplace ce mot par un autre dans une autre colonne mais sur la même ligne, exemple :

Image

Ici, à la ligne de la ref 17507, comme le mot 'HTC' est présent dans la colonne B, je remplacerais la marque (actuellement AEGIS) par HTC

Merci encore!

Re: exploitation fichier csv

Posté : 21 juil. 2014, 12:47
par sirakawa
@moogli d'abord:
connais-tu : http://www.mon-code.net/article/49/lire ... pl-de-php5 et si oui as-tu un avis?

Re: exploitation fichier csv

Posté : 21 juil. 2014, 16:30
par moogli
@ruben : oui c'est tout a fait possible.
mais dans ce cas il faut utiliser la chose ligne par ligne et non plus globale comme pour le dernier code.
donc soit avec file, soit avec fopen et consor.

@sirakawa ; du tout, effectivement je pourrais me tourner vers ce type de classe étant donnée que je m'en suis suis fait une similaire.
reste a voir les limites d'utilisation comme la taille des données maximal utilisable.
Cela simplifie largement le code.
<?php
<?php
$source = new SplFileObject('source.csv','r');
$source->setFlags(SplFileObject::READ_CSV);
$source->setCsvControl(';', '"', '"');
$cible = new SplFileObject('cible.csv','w');
foreach($source as $line){
    print_r($line);
    // modification de la ligne avec x règles de gestions le tout fait pas une fonction 
    $line = csvrule($line);
    $cible->fputcsv($line,',');
}
c'est quand même plus sympa à lire ;)

Normalement le coté perf devrait être la vu que c'est du natif.
C'est un peu dommage que l'on ne parle pas plus souvent des classes Spl c'est pas mal.

Merci pour l'info.

@+

Re: exploitation fichier csv

Posté : 21 juil. 2014, 17:48
par ruben06
Oui je m'en doutais que je devais passer par l’itération pour ce type de traitement...
Mais je n'ai aucune idée de comment m'y prendre dans le code, tu pense pouvoir me mettre sur la voie?


Merci

Re: exploitation fichier csv

Posté : 22 juil. 2014, 08:14
par sirakawa
Tu pux partir de ce cpde (qui développe ma première réponse):
<?PHP
$anciens = array("AEGIS", "BIDULOS");
$nouveaux  = array("Aegis", "Bidulos");
 $fp = fopen("new2.csv", "w+");
if (($handle = fopen("truc.csv", "r")) !== FALSE) 
{
     while (($ligne = fgetcsv($handle, 10000, ";")) !== FALSE) 
	{
	     $nouvelle_ligne = array();
	    $nouvelle_ligne = str_replace($anciens, $nouveaux, $ligne); //en modifiant cette ligne
                 fputcsv($fp, $nouvelle_ligne , ";");
      }
}
     fclose($handle);

?>

Re: exploitation fichier csv

Posté : 22 juil. 2014, 11:19
par ruben06
Tu pux partir de ce cpde (qui développe ma première réponse):
<?PHP
$anciens = array("AEGIS", "BIDULOS");
$nouveaux  = array("Aegis", "Bidulos");
 $fp = fopen("new2.csv", "w+");
if (($handle = fopen("truc.csv", "r")) !== FALSE) 
{
     while (($ligne = fgetcsv($handle, 10000, ";")) !== FALSE) 
	{
	     $nouvelle_ligne = array();
	    $nouvelle_ligne = str_replace($anciens, $nouveaux, $ligne); //en modifiant cette ligne
                 fputcsv($fp, $nouvelle_ligne , ";");
      }
}
     fclose($handle);

?>
Merci sirakawa,

c'est ce que j'ai fait, j'ai juste rajouter un troisieme parametre ";" a fputcsv pour regler mon soucis de valeur sur la meme colonne ;)

Re: exploitation fichier csv

Posté : 22 juil. 2014, 11:27
par moogli
Modération :
Puisque ta question est résolue, je l'indique en cliquant sur le bouton "Mettre le sujet en tant que Résolu" pour que les futures personnes qui voudront consulter ce sujet sachent qu'il contient une solution.

Tu peux réaliser cette opération toi-même en cliquant sur le bouton vert situé en haut de la page à côté du titre, si tu as posté le 1er message en tant que membre (inscrit et identifié).

Alors... inscris-toi !!! ;)