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

  • pfump
    hat ein Thema erstellt CSV-Datei aufteilen!?.

    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?

  • pfump
    antwortet
    Wegen der Sache mit dem Array.
    Ich muß gestehen das ist ja ne total einfache und gute Variante.
    War wohl zu einfach für mich. Ich hab mal wieder viel zu kompliziert gedacht

    Übrigens hab beide Probleme lösen können.
    Wegen dem Weglassen der 1.Zeile prüfe ich einfach welcher Wert an erster Stelle steht:
    PHP-Code:
    if($werte[0]!="Hersteller_Artikelnummer"){
    ...

    Und zum Problem mit preg_replace() hab ich das jetzt so gemacht:
    PHP-Code:
    $such=array('#[^a-z0-9äöü/]#i','/ä/','/ö/','/ü/','/\//'); 
    $replace=array('-','ae','oe','ue','');

    preg_replace($such,$replace,str_replace(" ","-",$werte[6])) 
    Wenn jemand noch Verbesserungsvorschläge hat, nur her damit

    Einen Kommentar schreiben:


  • pfump
    antwortet
    Danke. Funktioniert prima. Mußte es nur minimal anpassen:
    PHP-Code:
    $src file(dirname(__FILE__).'/../import/preisliste.csv'); //Quelle
    $dst $this->openCsvFile("kategorien.csv"); //Ziel
    $zaehler=2//weil ID 1 schon vergeben 
    $such=array('/+/','/ä/','/ö/','/ü/','/\//'); //Suchkriterien
    $replace=array('-','ae','oe','ue',''); //Replacements
    $namen = array(); //Arbeitsarray

    foreach($src as $zeile) {
       
    $werte explode(';'$zeile); // CSV Datenzeile in Array umwandeln
       
    if (!in_array($werte[6], $namen)) { // vorausgesetzt der Name steht an Position 3
          
    $namen[].= $werte[6]; // aufnehmen ins Array der bearbeiteten Namen
          
    $text=($zaehler).";1;".utf8_encode($werte[6]).";".utf8_encode($werte[4]).";;;;;".preg_replace($such$replaceutf8_encode($werte[6])).";".$werte[21]."\n";
          
    fwrite($dst$text); // komplette Zeile ins Ziel schreiben        
          
    $zaehler++;
       }
    //foreach 
    Jetzt hab ich aber noch 2 Probleme.
    Das erste, wie lasse ich die erste Zeile weg?
    Und das 2. größere Problem ist das perg_replace.
    Beim Ausführen erhalte folgende Fehlermeldung:
    Code:
    Warning:  preg_replace() [function.preg-replace]:  Compilation failed: nothing to repeat at offset 0 in ...  on line 130

    Einen Kommentar schreiben:


  • lstegelitz
    antwortet
    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..

    Einen Kommentar schreiben:


  • pfump
    antwortet
    Hat denn keiner einen Vorschlag

    Einen Kommentar schreiben:


  • pfump
    antwortet
    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.

    Einen Kommentar schreiben:


  • Wolla
    antwortet
    warum willst du diese 11.000-er Minidatei überhaupt noch splitten? Das sind doch auch für eine nur winzig ausgestattete Linuxkiste noch peanuts.

    Einen Kommentar schreiben:


  • pfump
    antwortet
    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?

    Einen Kommentar schreiben:


  • pfump
    antwortet
    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?

    Einen Kommentar schreiben:


  • ChrisB
    antwortet
    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

    Einen Kommentar schreiben:


  • pfump
    antwortet
    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?

    Einen Kommentar schreiben:


  • pfump
    antwortet
    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.

    Einen Kommentar schreiben:


  • ChrisB
    antwortet
    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.

    Einen Kommentar schreiben:


  • pfump
    antwortet
    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

    Einen Kommentar schreiben:


  • lstegelitz
    antwortet
    - 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

    Einen Kommentar schreiben:

Lädt...
X