Sehr große Datei in Teilschritten auslesen.

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von tibrandt, 23.03.2011.

  1. #1 tibrandt, 23.03.2011
    Zuletzt bearbeitet: 23.03.2011
    tibrandt

    tibrandt Grünschnabel

    Dabei seit:
    23.03.2011
    Beiträge:
    2
    Zustimmungen:
    0
    Hallo an das Forum,

    ich brauche Eure Hilfe, der Groschen will bei mir nicht fallen:
    Ich habe eine sehr große Datei mit „über“ 100000 Zeilen. Die Daten muss ich Zeilenweise auslesen und in eine DB einlesen.
    Meine Lösung, diese Komplett in ein Array zu pumpen, funktioniert, ist aber wegen der Größe der Datei sehr langsam.
    Deshalb möchte ich in 1000 Zeilen schritten das einlesen vornehmen:
    Programmablauf soll sein, 1000 Zeilen einlesen, diese verarbeiten um denn die nächsten 1000 einzulesen, bis das Ende der Datei erreicht ist.

    Mein Lösungsansatz ohne Schritte beginnt hier:
    Code:
    unset TEMPO
    ZEILENNUM=1
    for ((p=1; $p<=$(wc -l $import | awk '{print $1}'); p++));do
                    TEMPO[ZEILENNUM]=$(head -n$p $import | tail -n1)
                    ZEILENNUM=$(($ZEILENNUM+1))
    done 
    
    Es ist bestimmt ganz einfach, ich sehe es aber leider nicht.

    Nachtrag:
    Eine Bash ist eigentlich nicht so optimal für die Bearbeitung solch großer Dateien. Aber mein Programm hätte die ganze Nacht Zeit dafür. Der Lösungsansatz soll nur zeigen, in welche Richtung ich will. Normal lese ich Dateien über eine Funktion ein z.B.
    Code:
      
    function transf()
    {
    ZEILENNUM=1
    TRANF=$(cat "$1" | tr "'" ' ')
    OLDIFS=$IFS
    IFS=$'\n'
    for foo in ${TRANF}; do
            MEM[ZEILENNUM]=$foo
            ZEILENNUM=$(($ZEILENNUM+1))
    done
    IFS=$OLDIFS
    }
    
    Über
    Code:
    transf "datei.csv"
    
    geht das einlesen in das Array schon sehr schnell, aber das verarbeiten nicht.

    Danke!
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 HeadCrash, 23.03.2011
    HeadCrash

    HeadCrash Routinier

    Dabei seit:
    16.05.2009
    Beiträge:
    482
    Zustimmungen:
    1
    Ort:
    Bayern
    Hallo,

    zum Aufteilen einer Datei gibt es das nette Kommando "split".

    mfg
    HeadCrash
     
  4. #3 tibrandt, 24.03.2011
    tibrandt

    tibrandt Grünschnabel

    Dabei seit:
    23.03.2011
    Beiträge:
    2
    Zustimmungen:
    0
    Danke, das war die Lösung!

    Gruß
    tibrandt
     
  5. #4 allesmueller, 25.03.2011
    allesmueller

    allesmueller Eroberer

    Dabei seit:
    05.07.2005
    Beiträge:
    69
    Zustimmungen:
    0
    auch wenn du schon eine Lösung hast verstehe ich nicht warum die ganze Datei im Memory haben willst (vllt gibt es ja Gründe) . ich würde das so abarbeiten, statt dem echo käme dann die Erledigung der Zeile


    Code:
    $ cat test.sh
    #!/bin/bash
    
    i=1
    old_IFS=$IFS
    IFS=$'\n'
    for line in $(cat "$1")  
    do  
       echo "=Zeilennr: $((i++))==$line==="  
    done  
    IFS=$old_IFS
    
    Aufruf ist dann:
    Code:
    test.sh grossedatei.txt
     
  6. #5 floyd62, 26.03.2011
    floyd62

    floyd62 Routinier

    Dabei seit:
    01.05.2007
    Beiträge:
    309
    Zustimmungen:
    0
    Hi,

    also mein Ansatz wäre etwa der folgende (im Beispiel einfach numerierte Ausgabe von 10er-Blöcken aus der /etc/passwd:
    Code:
    #!/bin/bash
    
    
    DATA=/etc/passwd
    CHUNKSIZE=10
    
    
    process() {
            for ARG in "$@"; do
                    echo "$ARG"
            done | pr -t -n
    }
    
    
    declare -a LINES
    
    I=0
    exec 3<$DATA
    
    while read LINE <&3; do
            LINES[$I]="$LINE"
            let I++
    
            [ $(($I % $CHUNKSIZE)) = 0 ] && {
                    process "${LINES[@]}"
                    LINES=()
    
                    echo
                    I=0
            }
    done
    
    process "${LINES[@]}"
    
    @tibrandt:

    In deinem Original-Ansatz fällt mir zunächst einmal auf, dass du bei jedem Schleifendurchlauf die ganze Eingabedatei (wegen $(wc -l $input) einmal komplett einliest; das liesse sich einfach dadurch beheben, dass du die Länge der Eingabe schon vor dem Eintritt in die Schleife bestimmst. (Statt mit 'awk' kannst du dabei das eigentliche Ergebnis direkt bekommen, wenn du 'wc -l <$input' verwendest.)

    Richtig langsam dürfte das ganze aber dadurch werden, dass du in der Loop die Eingabe (mit 'head') immer wieder vom Anfang bis zu der Zeile liest, die dich gerade interessiert - deine Laufzeit geht also mit dem Quadrat der zu verarbeitenden Zeilen hoch ...

    @allesmueller:

    Liest du mit $(cat "$1") nicht auch die ganze Datei in den Speicher ein?

    Grüsse, A.
     
  7. #6 allesmueller, 26.03.2011
    allesmueller

    allesmueller Eroberer

    Dabei seit:
    05.07.2005
    Beiträge:
    69
    Zustimmungen:
    0
    floyd62, du hast mich beim Nichtnachdenken ertappt, Mist :)
    Deine Lösung ist ganz klar zu bevorzugen.

    Bestenfalls könnte man noch mit
    Code:
    cat $1 | while read line; do
       echo $line
    done
    
    arbeiten. Aber das liest zeichenweise ein - suboptimal - ausserdem ein Bsp für useless use of cat :)
     
  8. #7 Flunsch, 03.12.2011
    Flunsch

    Flunsch Grünschnabel

    Dabei seit:
    03.12.2011
    Beiträge:
    3
    Zustimmungen:
    0
    Hallo,
    man kann so eine große Datei heutzutage auch einfach so in eine Datenbank laden. Dafür hält jede größere Datenbank ein eigenes Tool bereit:

    MySQL - mysqlimport
    Oracle - SQL*Loader
    Sybase - bcp
    ...

    Damit dürfte der Import von 100.000 Zeilen auf einen Schlag keine Probleme bereiten. Ich nehme mal an, dass bei dieser Datei mit den über 100.000 Zeilen jede Zeile gleich aufgebaut ist (Felder getrennt durch Komma oder andere Trennzeichen), nur dass nicht immer alle Felder gefüllt sind.
    Man erstellt in der Datenbank eine Import-Tabelle, die ungefähr so aufgebaut ist wie die Datei. D.h. mindestens die Felderanzahl muss stimmen. Man kann die Felder aber auch gleich schon mal entweder als Text oder Zahlen formatieren.
    Also Hauptsache die Daten sind irgendwie schon mal in der Datenbank drinnen. Eine (große) Datenbank (meistens auf einem schnellen Rechner oder Server) hat sehr effektive Mittel, um dann die Daten weiterzuverarbeiten.
     
  9. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  10. #8 marcellus, 03.12.2011
    marcellus

    marcellus Kaiser

    Dabei seit:
    09.05.2007
    Beiträge:
    1.392
    Zustimmungen:
    0
    Willkommen im Unixboard,

    der Thread ist 8 Monate alt, bitte grab keine Leichen aus.
     
  11. #9 Flunsch, 04.12.2011
    Flunsch

    Flunsch Grünschnabel

    Dabei seit:
    03.12.2011
    Beiträge:
    3
    Zustimmungen:
    0
    Hallo marcellus,
    Danke für die Begrüßung. Ich gebe zu ich habe nicht geschaut, ob irgendwo anders diese Möglichkeit des bulk-copy erwähnt worden ist. Ich werde das noch nachholen, falls vorhanden, und dort meinen Beitrag reinstellen. Aber manchmal lohnt es sich ja trotzdem auch in einem alten Thread zu antworten, wenn es z.B. sonst noch keinen richtigen Platz gibt. Die Zahl der Klicks
     
Thema:

Sehr große Datei in Teilschritten auslesen.

Die Seite wird geladen...

Sehr große Datei in Teilschritten auslesen. - Ähnliche Themen

  1. Nordrhein-Westfalen: In sehr kleinen Schritten zu freier Software

    Nordrhein-Westfalen: In sehr kleinen Schritten zu freier Software: Die Landesregierung von Nordrhein-Westfalen hat auf eine Kleine Anfrage der Piratenfraktion im Landtag bezüglich proprietärer Software und Formate...
  2. umount sehr langsam, device mapper schuld ?

    umount sehr langsam, device mapper schuld ?: Hi Leute, ich habe mal wieder ein verrücktes Problem, das ich nicht ganz nachvollziehen kann. Folgendes vorgehen: - erstellen eines...
  3. pm-suspend sehr langsam

    pm-suspend sehr langsam: Hallo zusammen Ich habe auf meinem neuen Sony Vaio VPCw12S1E ein CrunchBang 10 mit wmii installiert. Soweit funktioniert alles prächtig....
  4. Sehr seltsam, Datei nur als user sichtbar, dann ganz verschwunden.

    Sehr seltsam, Datei nur als user sichtbar, dann ganz verschwunden.: Heute bin ich mal richtig ratlos. Ich hatte mir die neuesten Treiber fuer NVIDIA-Grafik:...
  5. Samab - Dateien öffnen sehr langsam

    Samab - Dateien öffnen sehr langsam: Hallo Zusammen, ich bin Admin für eine kleine Firma mit 5 Mitarbeitern. Es sind 6 Arbeitsplatzrechner (5 Windows XP , 1 Windows 7) im Einsatz....