Daten auslesen und in ein Excel file übertragen



  • Muss ich gleich mal ausprobieren. Hab aber noch ein weiters kleines Problemchen, und zwar wie kann ich einen Datei-Pfad festlegen, in dem es das log File sucht, mache es bisher immer mit manueller Eingabe und einscannen mit scanf, was nicht gerade sonderlich komfortabel ist.
    Thx Marc



  • Hallo Marc,

    du kannst z.B. dir den Pfad in der Umgebungsvariable PATH anlegen und mit der Funktion getenv auslesen. Musst du mal ein bisschen nach googeln, da die Umgebungsvariablen bei jedem Betriebssystem ein wenig voneinander abweichen.

    Dennis



  • Marc_1999 schrieb:

    Starting BFS "5889123f3fc381" on 17-AUG-2003 21:04:21 (5000.008 MB)
    "E:..." for 5000.008 MB
    Finished BFS "5889123f3fc381" (931 secs, 5.371 MB/s) on 17-AUG-2003 21:19:52

    Starting BFS "5889143f3fc381" on 17-AUG-2003 21:19:52 (650.008 MB)
    "E:\..." for 650.008 MB
    Finished BFS "5889143f3fc381" (100 secs, 6.500 MB/s) on 17-AUG-2003 21:21:32

    Starting BFS "5940563f48fe13" on 24-AUG-2003 20:04:07 (80.648 MB)
    "E:\..." for 80.648 MB
    Finished BFS "5940563f48fe13" (312 secs, 0.258 MB/s) on 24-AUG-2003 20:09:19

    Starting BFS "5940573f48fe13" on 24-AUG-2003 20:09:19 (7000.008 MB)
    "E:\..." for 7000.008 MB
    Finished BFS "5940573f48fe13" (2602 secs, 2.690 MB/s) on 24-AUG-2003 20:52:41

    Hi Descartes, danke für die angebotene Hilfe, also ich möchte eben aus diesem Logfile (ist nur ein Auschnitt) in der ersten Zeile das Datum
    und die MB auslesen, und diese dann in der Excel Tabelle in Spalten sortiert nach Datum und MB ausgeben.
    Mein Problem ist, das ich das File nach "Starting" durchsuchen muss um dann Datum und MB auszulesen,
    weil sonst würde ich ja die MB zahl doppelt lesen da die in der Zeile darunter ja nochmals steht.

    OK, immer drei Zeilen gehören zu einander.

    Das kann man sehr bequem mit einer Kombination aus SED und AWK machen.

    Zuerst werfen wir mal alle leeren Zeilen raus:

    sed -e '/^$/d' logfile
    

    Dann ändern wir das Format des Logfile so, dass alle Informationen die zusammengehören in einer Zeile stehen:

    sed -e ':a;$!N;s/\n\("\)/ \1/;ta;$!N;s/\n\(Finished\)/ \1/;ta;P;D' logfile
    

    In Kombination ergibt dies den Befehl:

    sed -e '/^$/d' logfile | \
    sed -e ':a;$!N;s/\n\("\)/ \1/;ta;$!N;s/\n\(Finished\)/ \1/;ta;P;D'
    

    Als Ausgabe erhalten wir:

    Starting BFS "5889123f3fc381" on 17-AUG-2003 21:04:21 (5000.008 MB) "E:..." for 5000.008 MB Finished BFS "5889123f3fc381" (931 secs, 5.371 MB/s) on 17-AUG-2003 21:19:52
    Starting BFS "5889143f3fc381" on 17-AUG-2003 21:19:52 (650.008 MB) "E:\..." for 650.008 MB Finished BFS "5889143f3fc381" (100 secs, 6.500 MB/s) on 17-AUG-2003 21:21:32
    Starting BFS "5940563f48fe13" on 24-AUG-2003 20:04:07 (80.648 MB) "E:\..." for 80.648 MB Finished BFS "5940563f48fe13" (312 secs, 0.258 MB/s) on 24-AUG-2003 20:09:19
    Starting BFS "5940573f48fe13" on 24-AUG-2003 20:09:19 (7000.008 MB) "E:\..." for 7000.008 MB Finished BFS "5940573f48fe13" (2602 secs, 2.690 MB/s) on 24-AUG-2003 20:52:41
    

    Jetzt müssen wir nur noch die für uns wichtigen Spalten herausschneiden. Hierzu nehmen wir AWK.

    AWK trennt eine Zeile per Default an Leerzeichen auf und nummeriert die Spalten beginnend mit $1 durch ($0 bezeichnet die komplette Zeile). Beispiel:

    $1       $2  $3               $4 $5          $6       $7        $8  $9      $10 $11      $12 $13      ...
    Starting BFS "5889123f3fc381" on 17-AUG-2003 21:04:21 (5000.008 MB) "E:..." for 5000.008 MB  Finished ...
    

    Als Ausgabeformat hätte ich gerne "<Datum> <Uhrzeit>;<Dateigroesse> <Einheit>;<Dateiname>" also benötige ich die Spalten $5, $6, $11, $$12, $9:

    awk '/^Starting/ { printf("%s %s;%s %s;%s\n", $5, $6, $11, $12, $9); }'
    

    In gänze sieht jetzt unser Befehl so aus:

    sed -e '/^$/d' logfile | \
    sed -e ':a;$!N;s/\n\("\)/ \1/;ta;$!N;s/\n\(Finished\)/ \1/;ta;P;D' | \
    awk '/^Starting/ { printf("%s %s;%s %s;%s\n", $5, $6, $11, $12, $9); }'
    

    Ergebnis:

    17-AUG-2003 21:04:21;5000.008 MB;"E:..."
    17-AUG-2003 21:19:52;650.008 MB;"E:\..."
    24-AUG-2003 20:04:07;80.648 MB;"E:\..."
    24-AUG-2003 20:09:19;7000.008 MB;"E:\..."
    

    Oder vielleicht lieber Tabulator getrennt?

    sed -e '/^$/d' logfile | \
    sed -e ':a;$!N;s/\n\("\)/ \1/;ta;$!N;s/\n\(Finished\)/ \1/;ta;P;D' | \
    awk '/^Starting/ { printf("%s %s\t%s %s\t%s\n", $5, $6, $11, $12, $9); }'
    
    17-AUG-2003 21:04:21    5000.008 MB     "E:..."
    17-AUG-2003 21:19:52    650.008 MB      "E:\..."
    24-AUG-2003 20:04:07    80.648 MB       "E:\..."
    24-AUG-2003 20:09:19    7000.008 MB     "E:\..."
    

    Einschränkung:
    Das ganze funktioniert nur korrekt, solange die Dateinamen keine Leerzeichen enthalten da sich ansonsten die Spaltennummern beim AWK Statement verschieben.

    Fertig.

    HTH
    Descartes



  • Marc_1999 schrieb:

    Hi Descartes, danke für die angebotene Hilfe, also ich möchte eben aus diesem Logfile (ist nur ein Auschnitt) in der ersten Zeile das Datum
    und die MB auslesen, und diese dann in der Excel Tabelle in Spalten sortiert nach Datum und MB ausgeben.

    Ok, dann lasse ich mal den Dateinamen weg und verwende nur noch $5, $6, $7 und $8 -- muss dann aber bei $7 und $8 die runden Klammern wegschneiden. Schlussendlich wird das ganze noch durch "sort" gejagt und sortiert:

    $1       $2  $3               $4 $5          $6       $7        $8  $9      $10 $11      $12 $13      ... 
    Starting BFS "5889123f3fc381" on 17-AUG-2003 21:04:21 (5000.008 MB) "E:..." for 5000.008 MB  Finished ...
                                     ^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^^ ^^^
    
    sed -e '/^$/d' logfile | \
    sed -e ':a;$!N;s/\n\("\)/ \1/;ta;$!N;s/\n\(Finished\)/ \1/;ta;P;D' | \
    awk '/^Starting/ { printf("%s %s\t%s %s\n", $5, $6, $7, $8); }' | \
    sed -e 's/[(,)]//g' | \
    sort
    

    bzw. (Tab getrennt)

    sed -e '/^$/d' logfile | \
    sed -e ':a;$!N;s/\n\("\)/ \1/;ta;$!N;s/\n\(Finished\)/ \1/;ta;P;D' | \
    awk '/^Starting/ { printf("%s %s;%s %s\n", $5, $6, $7, $8); }' | \
    sed -e 's/[(,)]//g' | \
    sort
    

    Du kannst natürlich die Dateigrössen auch schön rechtsbündig formatieren, indem du in dem awk-Kommando printf() den dritten printf-Parameter als "%<Feldbreite>s" definierst. Zwölf Zeichen sollten ausreichen.

    sed -e '/^$/d' logfile | \
    sed -e ':a;$!N;s/\n\("\)/ \1/;ta;$!N;s/\n\(Finished\)/ \1/;ta;P;D' | \
    awk '/^Starting/ { printf("%s %s\t%12s %s\n", $5, $6, $7, $8); }' | \
    sed -e 's/[(,)]//g' | \
    sort
    

    Ergebnis:

    17-AUG-2003 21:04:21       5000.008 MB
    17-AUG-2003 21:19:52        650.008 MB
    24-AUG-2003 20:04:07         80.648 MB
    24-AUG-2003 20:09:19       7000.008 MB
    


  • Wenn du die Folgezeilen eh nicht benötigst, dann reicht es aus die Zeilen zu berücksichtigen die mit "Starting" beginnen:

    cat logfile | \
    awk '/^Starting/ { printf("%s %s\t%12s %s\n", $5, $6, $7, $8); }' | \
    sed -e 's/[(,)]//g' | \
    sort
    

    wobei man sich das "cat" sparen kann, wenn man den Dateinamen des Logfile direkt hinter den AWK Befehl schreibt:

    awk '/^Starting/ { printf("%s %s\t%12s %s\n", $5, $6, $7, $8); }' logfile | \
    sed -e 's/[(,)]//g' | \
    sort
    

    Ergebnis ist das selbe wie oben.



  • Also mein code sieh momentan so aus:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    int main (void)
    {
    char filename[21]; // Dateiname
    char *c;
    char readbuffer[102];
    FILE *ifp; // Zeiger auf Datenstruktur FILE
    FILE *ofp;

    printf (" Filename der Logdatei?");
    scanf ("%s", filename);
    if ((ifp = fopen (filename, "r")) == NULL)
    {
    printf( "Datei %s nicht gefunden\n", filename);
    exit(1);
    };
    ofp = fopen ("out.csv","w");

    while (fgets(readbuffer, 100, ifp ) != NULL)
    {
    c = strstr(readbuffer, "Starting");
    if (c != NULL)
    printf("\n%s", readbuffer);

    static const "(" *find(const "(" *x, size_t n, const "("& y);
    }
    fclose(ifp); fclose (ofp);
    return 0;
    }

    So und jetzt komm ich nicht weiter, wie kann ich hier jetzt die Suche und das auslesen des Datums und der MB-Zahl integrieren um dieses dann in einem csv oder excel file einzutragen???
    Danke schon mal



  • @ Descartes

    Danke aber soweit ich weiß kann ich SED und AWK nur unter Linux bzw. simuliert mit Cygwin nutzen, ich programmier gerade auf Visual C++ und dort kann ich es leider nicht einbinden, aber danke war sehr interessant.
    Cu Marc



  • it Cygwin ist keine Simulation. Es funktioniert wirklich, ich benutze es regelmäßig für "batch-processe" unter NT und W2000

    Mit Cygwin hat man eine Menge sinnvoller Kommandozeilentools, die einem unter M$ fehlen.

    Schau mal nach gawk, das funktioniert glaube ich ohne die cygwin.dll



  • [quote="Marc_1999"]Starting BFS "5889123f3fc381" on 17-AUG-2003 21:04:21 (5000.008 MB)
    "E:..." for 5000.008 MB
    Finished BFS "5889123f3fc381" (931 secs, 5.371 MB/s) on 17-AUG-2003 21:19:52

    Starting BFS "5889143f3fc381" on 17-AUG-2003 21:19:52 (650.008 MB)
    "E:\..." for 650.008 MB
    Finished BFS "5889143f3fc381" (100 secs, 6.500 MB/s) on 17-AUG-2003 21:21:32

    Starting BFS "5940563f48fe13" on 24-AUG-2003 20:04:07 (80.648 MB)
    "E:\..." for 80.648 MB
    Finished BFS "5940563f48fe13" (312 secs, 0.258 MB/s) on 24-AUG-2003 20:09:19

    Starting BFS "5940573f48fe13" on 24-AUG-2003 20:09:19 (7000.008 MB)
    "E:\..." for 7000.008 MB
    Finished BFS "5940573f48fe13" (2602 secs, 2.690 MB/s) on 24-AUG-2003 20:52:41

    Das vorletzte Posting von mir bezieht sich übrigends auf dieses Logfile, hatte ich vorhin vergessen zu erwähnen, sorry.
    Cu Marc



  • PAD schrieb:

    it Cygwin ist keine Simulation. Es funktioniert wirklich, ich benutze es regelmäßig für "batch-processe" unter NT und W2000

    Mit Cygwin hat man eine Menge sinnvoller Kommandozeilentools, die einem unter M$ fehlen.

    Schau mal nach gawk, das funktioniert glaube ich ohne die cygwin.dll

    Wenn du ein paar der Unix Tools unter Windows benötigst kannst du dir von http://unxutils.sourceforge.net/ den ZIP File "UnxUtils.zip" herunterladen.

    In dem Zip Container befinden sich im Verzeichnis usr\local\wbin u.a. die Dateien "sed.exe" und "gawk.exe". Diese beiden Dateien kannst du dir dann wohin-auch-immer kopieren. Eine DLL wie z.B. win32gnu.dll oder cygwin1.dll wird nicht benötigt.

    REM
    REM Windows Batch Datei zur Aufbereitung eines Logfile in ein Tab-separiertes Format
    REM
    gawk -- "/^Starting/ { printf(\"%%s %%s\t%%12s %%s\n\", $5, $6, $7, $8); }" logfile.txt | sed -e "s/[(,)]//g" | sort
    

Anmelden zum Antworten