Forum: PC-Programmierung Linux: von txt zu SQL-Script


von Ohio (Gast)


Lesenswert?

Hallo Forum,

ich habe mehrere txt-Dateien vorliegen, deren Daten ich in eine 
Datenbank einpflegen soll.

Die txt-Dateien haben alle die selbe Struktur

Spaltenname1         Inhalt1
Spaltenname2         Inhalt2
Spaltenname3         Inhalt3
Spaltenname4         Inhalt4
Spaltenname5         Inhalt5
<Leerzeile>
Spaltenname1         Inhalt1
Spaltenname2         Inhalt2
Spaltenname3         Inhalt3
Spaltenname4         Inhalt4
Spaltenname5         Inhalt5
<Leerzeile>
Spaltenname1         Inhalt1
...

Die Spaltenzahl ist innerhalb jeder txt-Datei konstant, aber in den 
verschiedenen txt-Dateien unterschiedlich.

Wie ließen sich daraus SQL-Anweisungen wie

INSERT INTO <Tabelle>
   (
     Spaltenname1,
     Spaltenname2,
     Spaltenname3,
     Spaltenname4,
     Spaltenname5
   )
VALUES
   (
      Inhalt1,
      Inhalt2,
      Inhalt3,
      Inhalt4,
      Inhalt5
   );

erzeugen?

von Peter II (Gast)


Lesenswert?

Ohio schrieb:
> Wie ließen sich daraus SQL-Anweisungen wie
> erzeugen?

z.b. mit einen kleinen Perlscript.

von Norbert (Gast)


Lesenswert?

...oder awk...

...oder Python...

...oder Bash...

...oder...


Tausend Wege führen hier nach Rom.

von Ohio (Gast)


Lesenswert?

Norbert schrieb:
> ...oder Bash...

genau hier suche ich die Lösung, wobei mir schon Teillösungen nicht 
gelingen.
Mein Gedanke war:
1) an jede Nicht-leere Zeilen am Anfang eine Absatznummerierung 
einzufügen
2) mir mit grep Schleifenweise die Absätze anzeigen
3) mit read über den Absatz SpaltennameX und InhaltX abspeichern
4) mit echo die Ausgabe in eine Datei zu erzeugen

an Punkt 1 hängt es gerade, die Scripte für sed finde ich eher 
undurchschaubar.

von Peter II (Gast)


Lesenswert?

Ohio schrieb:
>> ...oder Bash...
>
> genau hier suche ich die Lösung, wobei mir schon Teillösungen nicht
> gelingen.

warum ausgerechnet bash? Das ist nun wirklich das ungeigneteste für 
diesen zweck. AWK oder Perl sind für diese zwecke besser.

von Norbert (Gast)


Lesenswert?

Ohio schrieb:
> Norbert schrieb:
>> ...oder Bash...
>
> genau hier suche ich die Lösung, wobei mir schon Teillösungen nicht
> gelingen.
> Mein Gedanke war:
> 1) an jede Nicht-leere Zeilen am Anfang eine Absatznummerierung
> einzufügen
> 2) mir mit grep Schleifenweise die Absätze anzeigen
> 3) mit read über den Absatz SpaltennameX und InhaltX abspeichern
> 4) mit echo die Ausgabe in eine Datei zu erzeugen
>
> an Punkt 1 hängt es gerade, die Scripte für sed finde ich eher
> undurchschaubar.

Es geht zwar mit allen genannten Werkzeugen, aber Bash steht nicht 
umsonst an dritter Stelle;-)

Wie PeterII bereits schrieb, nimm awk, perl, python, was immer du am 
besten beherrschst.

von Vlad T. (vlad_tepesch)


Lesenswert?

kleiner Tip:

leerer String für fields,
leerer String für values

textdatei zeilenweise einlesen.
ist zeile nicht leer:
  zeile aufteilen
  fields string um neues feld ergänzen
  values string um neuen value ergänzen
sonst
  "INSERT INTO tabelle (" + fields + ")VALUES(" + values + ");"
  ausgeben
  fields und values wieder auf leer setzen

von Ohio (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> kleiner Tip:
>
> .....


der Tip war prima, es klappt! (fast)

mein Script sieht nun so aus:
1
#!/bin/bash
2
3
DATEI=/home/user1/test.tmp
4
FIELDS=""
5
VALUES=""
6
7
while read line
8
do
9
   if [ ! -z "$line" ] ; then 
10
      read F V
11
      if [ ! -z "$FIELDS" ] ; then
12
         FIELDS="$FIELDS, $F"
13
         VALUES="$VALUES, $V"
14
      else
15
         FIELDS="$F"
16
         VALUES="$V"
17
      fi
18
   else
19
      if [ ! -z "$FIELDS" ] ; then
20
         echo "INSERT INTO tabelle ($FIELDS) VALUES ($VALUES);"
21
      fi
22
      FIELDS=""
23
      VALUES=""
24
   fi
25
done < $DATEI

meine Ausgabe sieht so aus:
1
INSERT INTO tabelle (Spaltenname2, Spaltenname4, Spaltenname6) VALUES (Inhalt2, Inhalt4, Inhalt6);
2
INSERT INTO tabelle (Spaltenname2, Spaltenname4, Spaltenname6) VALUES (Inhalt2, Inhalt4, Inhalt6);
3
INSERT INTO tabelle (Spaltenname2, Spaltenname4, Spaltenname6) VALUES (Inhalt2, Inhalt4, Inhalt6);
4
INSERT INTO tabelle (Spaltenname2, Spaltenname4, Spaltenname6) VALUES (Inhalt2, Inhalt4, Inhalt6);
5
INSERT INTO tabelle (Spaltenname2, Spaltenname4, ) VALUES (Inhalt2, Inhalt4, );

es fehlen mir jeweils die ungeraden Zeilennummern - wo könnten die denn 
verloren gegangen sein?

Dank

von Norbert (Gast)


Lesenswert?

Du musst - wenn du eine Leerzeile gelesen hast - solange eine weitere 
Leseschleife laufen lassen bis wieder eine Leerzeile auftaucht.

PS.
Hoffentlich enthalten deine Inhalte keine <spaces>!

von Ohio (Gast)


Lesenswert?

Norbert schrieb:
> Du musst - wenn du eine Leerzeile gelesen hast - solange eine weitere
> Leseschleife laufen lassen bis wieder eine Leerzeile auftaucht.

Das verstehe ich leider nicht.
Die Ausgabe bei Leerzeilen an sich klappt ja, das Problem sehe ich beim 
Zusammensetzen der Variablen bei Nicht-Leerzeilen.

Liest eventuell das
1
 read F V
 schon die nächste Zeile an, anstelle im Inhalt von $line?

Norbert schrieb:
> Hoffentlich enthalten deine Inhalte keine <spaces>!

Das kann ich leider nicht ausschließen - werde ich dort ein Problem mit 
dem Read bekommen?

von Vlad T. (vlad_tepesch)


Lesenswert?

Ich kann kein bash, aber ich denke das problem ist, dass du zweimal 
ließt:
1
while read line
2
do
3
   if [ ! -z "$line" ] ; then 
4
      read F V
du darfst natürlich nicht, wenn du festgestellt hast, dass die Zeile 
NICHT leer war, gleich die nächste einlesen.

Edit:
Ohio war schneller

von Norbert (Gast)


Lesenswert?

Ohio schrieb:

> Norbert schrieb:
>> Hoffentlich enthalten deine Inhalte keine <spaces>!
>
> Das kann ich leider nicht ausschließen - werde ich dort ein Problem mit
> dem Read bekommen?

Der read packt das erste Wort in F und - WIMRE - alle weiteren in V

Du bekommst ein Problem mit dem SQL INSERT.

Denn wenn's ein space beinhaltet, wird's wohl ein String sein.
Und der möchte gerne in  '  <<--- so etwas eingepackt werden.

von Valerie (Gast)


Lesenswert?

Bevor man hier irgendwelche Skripte schreibt wuerde ich mir mal 
"mysqlimport" genauer durchlesen.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

bei oracle und DB2 werden direkt Loader-Utilities mitgeliefert, z.B.

http://www.orafaq.com/wiki/SQL*Loader_FAQ

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.