Mit awk ein textfile parsen und SQL daraus erzeugen.

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von raz0rsedge, 19.02.2011.

  1. #1 raz0rsedge, 19.02.2011
    raz0rsedge

    raz0rsedge Grünschnabel

    Dabei seit:
    19.02.2011
    Beiträge:
    2
    Zustimmungen:
    0
    Hallo,

    ich hab ein (Verständnis)Problem mit awk. Der Plan ist, mit einem cronjob (awk Einzeiler)
    aus einem textfile Werte in eine vorhandene MySQL Datenbank zu schubsen. Dafür wollte ich aus diesem textfile via awk ein gültiges SQL-Statement erzeugen, welches dann in einer sqlstatement.php abgelegt und regelmäßig mit PHP aufgerufen wird.

    Mein Script:
    PHP:
    #! /usr/bin/awk -f
    BEGIN {
    FS="\n" #means newline is new field
    RS="};"
    printf "SET SQL_MODE=\"NO_AUTO_VALUE_ON_ZERO\";\n"
    printf "CREATE TABLE IF NOT EXISTS `phpkit2`.`Players` (\n"
    printf "  `id` int(11) NOT NULL AUTO_INCREMENT,\n"
    printf "  `name` varchar(100) NOT NULL AUTO_INCREMENT,\n"
    printf "  `customScore` int(11) NOT NULL,\n"
    printf "  `killsTotal` int(11) NOT NULL,\n"
    printf "  `killed` int(11) NOT NULL,\n"
    printf "  PRIMARY KEY (`id`),\n"
    printf "  KEY `name` (`name`)\n"
    printf ") ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;\n"
    printf "INSERT INTO `Players` (`name`, `customScore`, `killsTotal`, `killed`) VALUES\n"
    }
    {
    printf "("$1", "$2", "$3", "$4"),"
    }
    END {
    printf ";"
    }
    liest lokal aus dem immer so aufgebauten Textfile:
    Aber mit diesem zeilenweise parsen mach ich etwas falsch, so dass bei
    awk -f awkscript textfile.txt > sqlstatement.php
    erstmal nur das rauskommt:
    Ziel ist aber eigentlich
    ...
    INSERT INTO `Players` (`name`, `customScore`, `killsTotal`, `killed`) VALUES
    (mooonski, 56, 366, 12),
    ...
    ;


    Es ergeben sich mehrere Probleme:
    1. 1 Datensatz besteht aus 4 Zeilen ($1-$4?) nicht wie üblich 1 Zeile = 1 Datensatz
    2. Die Symbolfolge }; soll als Datensatz-Trenner erkannt werden (RS="};"?)
    3. mit grep/egrep -v müssen die Bezeichner noch weg, damit nur die Werte in die DB gelangen.

    Jetzt meine Fragen:

    Um awk das textfile schmackhaft zu machen, muss ich den Satztrenner }; mit Regex umschreiben oder geht das so wie oben im script?
    Wenn ich als Datenfeld-Trenner \n nehme, wie erreiche ich dann, dass immer 4 Felder in eine SQL Zeile kommen -> (mooonski, 56, 366, 12)?
    Momentan steh ich etwas auf der Leitung, vielleicht gibt es hier ja awk Experten, ich bitte um Mithilfe ;)


    Mein Sys:
    OS [Debian GNU/Linux]
    CPU [Quad-Core AMD Opteron 1385 clocked at 2700.000 Mhz]
    Kernel [Linux 2.6.26-2-amd64 x86_64]
    AWK [GNU Awk 3.1.5]

    greetz,
    raz0r

    /edit1
    Als shell verwende ich bash
     
  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, 20.02.2011
    Zuletzt bearbeitet: 20.02.2011
    HeadCrash

    HeadCrash Routinier

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

    sieht doch ganz vernünftig aus. Im Grunde fehlte dir nur ein "\n" beim Rowseperator RS.

    Code:
    #! /usr/bin/awk -f
    BEGIN {
    FS=";\n" #means newline is new field
    RS="};\n" 
    printf "SET SQL_MODE=\"NO_AUTO_VALUE_ON_ZERO\";\n"
    printf "CREATE TABLE IF NOT EXISTS `phpkit2`.`Players` (\n"
    printf "  `id` int(11) NOT NULL AUTO_INCREMENT,\n"
    printf "  `name` varchar(100) NOT NULL AUTO_INCREMENT,\n"
    printf "  `customScore` int(11) NOT NULL,\n"
    printf "  `killsTotal` int(11) NOT NULL,\n"
    printf "  `killed` int(11) NOT NULL,\n"
    printf "  PRIMARY KEY (`id`),\n"
    printf "  KEY `name` (`name`)\n"
    printf ") ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;\n"
    printf "INSERT INTO `Players` (`name`, `customScore`, `killsTotal`, `killed`) VALUES\n"
    }
    {
    # Kein Komma ausgeben falls es der erste Datensatz ist
    if( NR != 1 ) {
            printf ",\n"
    }
    # Feldbezeichnungne entfernen
    split($1,name,"=")
    split($2,customScore,"=")
    split($3,killsTotal,"=")
    split($4,killed,"=")
    
    printf "("name[2]", "customScore[2]", "killsTotal[2]", "killed[2]")"
    }
    END {
    printf ";\n"
    }
    
    Code:
    $ ./awk.sh textfile
    SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
    CREATE TABLE IF NOT EXISTS `phpkit2`.`Players` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(100) NOT NULL AUTO_INCREMENT,
      `customScore` int(11) NOT NULL,
      `killsTotal` int(11) NOT NULL,
      `killed` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `name` (`name`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs;
    INSERT INTO `Players` (`name`, `customScore`, `killsTotal`, `killed`) VALUES
    ("mooonski", 56, 366, 12),
    ("[AbuU]", 49, 164, 13),
    ("Hotcha", 19, 27, 4),
    ("Zevon", 0, 0, 0);
    
    mfg
    HeadCrash
     
  4. #3 raz0rsedge, 25.09.2011
    raz0rsedge

    raz0rsedge Grünschnabel

    Dabei seit:
    19.02.2011
    Beiträge:
    2
    Zustimmungen:
    0
    Oh danke, hab gar nicht mehr drann gedacht dass hier noch jemand antworten könnte =)
    Jawoll jetzt funktioniert alles... so ists prima.

    Vielen Dank.

    raz0r
     
Thema:

Mit awk ein textfile parsen und SQL daraus erzeugen.

Die Seite wird geladen...

Mit awk ein textfile parsen und SQL daraus erzeugen. - Ähnliche Themen

  1. SED: Zu bearbeitende Dateien aus Textfile einlesen

    SED: Zu bearbeitende Dateien aus Textfile einlesen: Tag zusammen, entweder ich suche nach den falschen Stichworten, oder ich mache was falsch. Mein Problem : Mit dem Befehl grep -Rsl...
  2. Ältestes Textfile aus einem Verzeichnis ausdrucken.

    Ältestes Textfile aus einem Verzeichnis ausdrucken.: ls *.txt -1t|tail -1 Dieser Befehl druckt mir das älteste *.txt-File aus dem aktuellen Verzeichnis aus (1=Spalte, t=sortiert nach Zeit und tail...
  3. Wie Zeilen mit weniger als 34 Zeichen aus einem Textfile löschen?

    Wie Zeilen mit weniger als 34 Zeichen aus einem Textfile löschen?: Ich möchte alle Zeilen mit weniger als 34 Zeichen aus einem Textfile löschen. Kennt jemand eine Möglichkeit über die Kommandozeile?
  4. Textfile mit Text separiert durch Leerzeile, wie letzten Text rausbekommen?

    Textfile mit Text separiert durch Leerzeile, wie letzten Text rausbekommen?: Hi, wie geschrieben, ich habe ein Textfile, welches quasi so aussieht: Text text text text text text text letzter text bevor...
  5. Textfile auf jeder Zeile bestimmtest Wort heraussuchen

    Textfile auf jeder Zeile bestimmtest Wort heraussuchen: Guten Tag miteinander, ich hätte kurz eine Frage, und zwar habe ich ein Logfile vormir, welches immer gleich aufgebaut ist, Beispiel: Mon...