Mit awk ein textfile parsen und SQL daraus erzeugen.

raz0rsedge

raz0rsedge

Grünschnabel
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:
name="mooonski";
customScore=56;
killsTotal=366;
killed=12;
};
name="[AbuU]";
customScore=49;
killsTotal=164;
killed=13;
};
name="Hotcha";
customScore=19;
killsTotal=27;
killed=4;
};
name="Zevon";
customScore=0;
killsTotal=0;
killed=0;
};

Aber mit diesem zeilenweise parsen mach ich etwas falsch, so dass bei
awk -f awkscript textfile.txt > sqlstatement.php
erstmal nur das rauskommt:
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
(
, name="mooonski";
, customScore=56;
, killsTotal=366;
),(
, name="[AbuU]";
, customScore=49;
, killsTotal=164;
),(
, name="Hotcha";
, customScore=19;
, killsTotal=27;
),(
, name="Zevon";
, customScore=0;
, killsTotal=0;
),

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
 
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
 
Zuletzt bearbeitet:
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
 

Ähnliche Themen

Prblem mit zeilenweises auslesen von Datei und schreiben nach mysql

Ausführbare C-Datei von Mac OS auf Embedded Linux ausführen

Akonadi startet nicht mehr

NagiosGrapher 1.7.1 funktioniert nicht

Fedora 20 - Unlösbare Paket-Duplikat Konflikte

Zurück
Oben