Ankündigung

Einklappen
Keine Ankündigung bisher.

CSV-Datei aufteilen!?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • CSV-Datei aufteilen!?

    Hallo,

    ich hab mal wieder ein Problem. Und zwar geht es darum eine große
    Anzahl von Werten einer CSV-Datei in mehrere Dateien aufzuteilen.
    In der Datei sind ca. 11000 Datensätze.
    Also sagen wir in der Datei sind die Werte:
    Code:
    id;name;Farbe;Aktiv;Anzahl
    1;Kabel;rot;1;150
    2;Apapter;grün;1;200
    3;Kabel;schwarz;1;300
    ...
    Jetz sollen die Werte für id, Name und Aktiv in eine neue Datei geschrieben werden.
    Es soll aber so sein, das wenn es den Namen in der neuen Datei schon gibt,
    dieser nicht mehr reingeschrieben wird.
    Ich hab mir das folgendermaßen gedacht:
    PHP-Code:
    $y=0;
    $handle fopen(dirname(__FILE__).'/../import/preisliste.csv''r'); //Quelldatei
     
    $fp fopen(dirname(__FILE__).'/../import/kategorien.csv''a+'); //Zieldatei

    for ($current_line 0$line fgetcsv($handleMAX_LINE_SIZE";"); $current_line++)
    {
       
    //1. Zeile weglassen (also die Spaltennamen)
       
    if($current_line!=0)
       {
          for (
    $x 0$zeile fgetcsv($fpMAX_LINE_SIZE";"); $x++)      
          {
             if(
    $line[4]==$zeile[2])
             {
                
    $y=1;
                break;
             }  
    //if line==zeile     
          
    //for-Schleife $x
          //Prüfen ob yungleich 1, wenn ja reinschreiben
          
    if($y!=1)
          {
             
    $text=($current_line+1).";1;".$line[4]."\n";
             
    fwrite($fp,$text);  
             
    $y=0;
          } 
    //if $y
          
    else $y=0;
       } 
    // if current_line
    //for-Schleife
    fclose($handle);
    fclose($fp); 
    Das Problem ist ich hab irgend einen Denkfehler drin.
    Leider funktioniert das nicht. Es steht immer alles drin.
    Weiß jemand ne Lösung oder eine andere Möglichkeit wie ich das machen könnte? So rein wegen der Performance?

  • #2
    Wird die Zieldatei jedesmal neu erstellt oder fortgeführt?

    Bei Neuerstellung kannst du dir die bereits geschriebenen Namen in einem Array merken und daraus abfragen.

    Bei Fortführung müsstest du das Array erstmal mit den Namen initialisieren, die bereits in der Zieldatei vorhanden sind.

    Was du NICHT machen solltest: Bei jedem Schreibvorgang die Zieldatei komplett durchsuchen - da bricht dir die Performance komplett weg
    Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

    Kommentar


    • #3
      Also die Zieldatei wird ja mit Attribut "a+" geöffnet.
      Weil ich ja die Namen anhängen muß die es noch nicht gibt.
      Desweiteren wird die jedes mal wenn das Script ausgeführt wird gelöscht
      bzw. neu angelegt.

      Könntest du mir das mit dem Array genauer erklären?
      Meinst du das ich zuerst ein Array anlege wo ich die Namen reinschreibe
      und auch darin suche ob es den schon gibt? Und wenn ich die Quelldatei durch habe, dann schreibe ich den Array komplett in die Zieldatei?
      Wie macht man denn sowas am besten?

      Kommentar


      • #4
        - Array anlegen
        - Quelldatei öffnen
        - Zeile lesen (und exploden..)
        - Ist Name bereits im Array? (hint: in_array())
        - ja -> nix machen, sonst Zieldatei schreiben UND Namen ins Array packen
        Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

        Kommentar


        • #5
          Also ich hab das jetzt so:
          PHP-Code:
          $test =array();
          $handle =fopen(dirname(__FILE__).'/../import/preisliste.csv''r'); //Quelldatei
           
          $fp =fopen(dirname(__FILE__).'/../import/kategorien.csv''a+'); //Zieldatei

             //für alle Zeilen der Quelldatei
          for ($current_line 0$line fgetcsv($handleMAX_LINE_SIZE";"); $current_line++)
          {
             
          //1. Zeile weglassen (also die Spaltennamen)
             
          if($current_line!=0)
             {
                if(
          $current_line==1)
                {
                   
          $text=($current_line+1).";1;".$line[4]."\n";
                   
          $test=$text//weil bei der 1.Zeile steht ja in der Datei noch nichts
                
          }    //if current_line==1
                
          else
                {
                   if(!
          in_array($line[4],$test))
                   {
                      
          $text=($current_line+1).";1;".$line[4]."\n";
                      
          $test.=$text;
                   } 
          //if in_array()
                
          //else-Zweig current_line==1
             
          //if current_line !=0
          }  //for-Schleife für alle Zeilen der CSV_Datei
          var_dump($test); 
          So müßte das doch im groben funktionieren oder?
          Leider erhalte ich da die Fehlermeldung:
          Code:
          Warning:  in_array() [function.in-array]:  Wrong datatype for second argument

          Kommentar


          • #6
            Zitat von pfump Beitrag anzeigen
            Leider erhalte ich da die Fehlermeldung:
            Code:
            Warning:  in_array() [function.in-array]:  Wrong datatype for second argument
            RTFM!
            PHP: in_array - Manual

            Die Parameter in der richtigen Reihenfolge anzugeben, kann doch nicht so schwer sein, immerhin hat's da sogar Beispiele.
            [SIZE="1"]RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?[/SIZE]

            Kommentar


            • #7
              Die Parameter in der richtigen Reihenfolge anzugeben, kann doch nicht so schwer sein, immerhin hat's da sogar Beispiele.
              Das hab ich gemacht!
              PHP-Code:
              in_array($line[4],$test
              $line[4] ist der jeweilige Name des Datensatzes aus der Datei.
              $test ist das Array, indem die Namen gespeichert werden.

              Was ich aber vergessen habe, sind die [] wenn ich was in $test schreibe:

              PHP-Code:
              $text=($current_line+1).";1;".$line[4]."\n";
              $test[]=$text//anstatt $test[$surrent_line]=$text; 
              So geht es zwar, aber in dem Array stehen trotzdem alle
              Namen drin, also auch doppelt.

              Kommentar


              • #8
                Ich glaub ich weiß jetzt warum alle Werte reingeschrieben werden.
                Es denke es liegt an:
                PHP-Code:
                $text=($current_line+1).";1;".$line[4]."\n"
                Da steht ja dann im Array z.B.:
                Code:
                [0]=> string(10) "1;1;Kabel "
                Ich suche ja nach dem Namen, also z.B. Kabel
                Im Array steht aber wie gesagt 1;1;Kabel .
                Und wie wir wissen:

                Code:
                1;1;Kabel != Kabel
                Das Problem ist aber, das ich die restlichen dazugehörigen Werte auch brauche! Ich steh zur Zeit total auf dem Schlauch.
                Hab ich mit meiner These recht? Und hat jemand ne Idee wie sich
                das Problem lösen läßt?

                Kommentar


                • #9
                  Zitat von pfump Beitrag anzeigen
                  Ich suche ja nach dem Namen, also z.B. Kabel
                  Dann extrahiere diesen an der Stelle, wo du den Vergleich durchführen möchtest.

                  Das Problem ist aber, das ich die restlichen dazugehörigen Werte auch brauche!
                  Später vielleicht, aber nicht für diesen Vergleich.

                  Was hältst du denn von:
                  - Namen extrahieren
                  - Vergleichen
                  - Wenn Vergleich erfolgreich, dann komplette Daten des Datensatzes in Ergebnis-Array übernehmen, sonst nicht
                  [SIZE="1"]RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?[/SIZE]

                  Kommentar


                  • #10
                    Um ehrlich zu sein, ich versteh grad nicht wie du das meinst.
                    Ein bisschen Quellcode wär vielleicht nicht schlecht...

                    Oder meinst du ich habe 2 Arrays. In dem einen speichere ich die Namen.
                    Mit diesem vergleiche ich die Namen ($line[4]) aus der Quelldatei.
                    Und wenn dort der Name nicht gefunden wird speichere ich ihn mit dem Rest in den 2. Array?

                    Kommentar


                    • #11
                      Wenn ich die Datei immer durchsuche,
                      hab ich jetzt hinbekommen das es klappt.
                      Sieht so aus:

                      PHP-Code:
                      $handle $this->openCsvFile(); 
                              
                      $y="";//$this->truncateTable('category'); //Kategorien löschen  
                              
                      $zaehler=2//ID 1 ist schon vergeben!
                              
                      for ($current_line 0$line fgetcsv($handleMAX_LINE_SIZE";"); $current_line++) 
                              { 
                              
                      $fp $this->openCsvFile("kategorien.csv"); 
                                  
                      //1. Zeile weglassen (also die Spaltennamen) 
                                  
                      if($current_line!=0
                                 { 
                                     for (
                      $x 0$zeile fgetcsv($fpMAX_LINE_SIZE";"); $x++)       
                                    { 
                                       if(
                      $current_line!=1
                                       {     
                                           if(
                      $line[4]==$zeile[2])
                                           { 
                                              
                      $y="vorhanden";
                                              break;
                                           } 
                      //if line==zeile      
                                      
                      }  //current_line!=1 
                                   
                      //for-Schleife zeile 
                                   
                      if($y!="vorhanden")
                                   { 
                                      
                      $text=($zaehler).";1;".$line[4]."\n"
                                      
                      fwrite($fp,$text);   
                                      
                      $zaehler++; 
                                   } 
                                   else 
                      $y="";     
                                } 
                      //current_line!=0 
                                
                      $this->closeCsvFile($fp);     
                             }  
                      //for-Schleife für alle Zeilen der CSV_Datei 
                             
                      $this->closeCsvFile($handle); 
                      Leider ist das von Seiten der Performance nicht gut.
                      Wie bekomm ich das jetzt mit nem Array hin?
                      Und wie schreib ich den Array dann in die Datei?

                      Kommentar


                      • #12
                        warum willst du diese 11.000-er Minidatei überhaupt noch splitten? Das sind doch auch für eine nur winzig ausgestattete Linuxkiste noch peanuts.
                        [PHP]if ($var != 0) {
                        $var = 0;
                        }[/PHP]

                        Kommentar


                        • #13
                          Bei der Datei handelt es sich um eine Preisliste.
                          Diese Liste soll in ein Shopsystem importiert werden.
                          Darum ist es notwendig, diese in mehrere angepaßte Dateien zu splitten,
                          um die Daten korrekt importieren zu können.
                          Und zwar in Kategorien, Produkte, Hersteller, Adressen, Kunden, Attribute
                          und Händler.
                          Es funktioniert zwar wenn ich die Datei jedes mal durchsuche, aber
                          ich denke mal für alle Dateien kann ich das nicht machen.

                          Kommentar


                          • #14
                            Hat denn keiner einen Vorschlag

                            Kommentar


                            • #15
                              Weil bald Wochenende ist:
                              PHP-Code:
                              $src file('/pfad/Quelldatei');
                              $dst fopen('/pfad/Zieldatei''w+');
                              $processed = array();

                              foreach(
                              $src as $row) {
                                  
                              $data explode(';'$row); // CSV Datenzeile in Array umwandeln
                                  
                              if (!in_array($data[2], $processed) { // vorausgesetzt der Name steht an Position 3
                                      
                              $processed[] $data[2]; // aufnehmen ins Array der bearbeiteten Namen
                                      
                              $fwrite($dst$row); // komplette Zeile ins Ziel schreiben
                                  
                              }
                              }
                              fclose($dst); 
                              ungetestet..
                              Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                              Kommentar

                              Lädt...
                              X