Hallo Liste, habe ein Frage an die MySQL Spezialisten, da ich mich damit nicht so sehr auskenne benötige ich bei folgendem Problem Eure Hilfe. Datenbank hat 1 Tabelle mit 6 Spalten 1 Spalte ist der Primärschlüssel, d.h. pro Zeile ein Wert. Die gesamte Datei besteht nur aus rd. 470 000 Zeilen. In der Spalte 2 beginnt jeder Datensatz für den Kunden mit dem Namen KUNDENKARTE und dann kommen unterschiedlich lange Zeilen und Zeilenanzahlen. Key Feld1 Feld2 Feld 3 usw 000001 KUNDENKARTE der Rest der Felder ist leer BLANK 000002 Text Text Text 000080 KUNDENKARTE 81 Text Text Text 00471255 letzter Satz in der Datei. Also zwischen den Zeilen 00001 und 00079 soll ein KUNDENSATZ -KEY im neuen Feld 7 in der Art Kunde 00001 Kunde 00002 usw erstellt werden. Mit welchem Befehl könnte ich es machen, das nachher die Datenbank so aussieht: Key Feld1 ---- Feld7 (Kunde) 0001 KUNDENKARTE 00001 0080 KUNDENKARTE 00002 wenn alle zum Kunden 1 gehörigen Zeilen auch im Feld7 den Wert wie hier im Beispiel den Wert 0001 --- 00002 000003 usw haben ist es auch ok. Leider ist eine Bearbeitung mit OpenOffice nicht möglich, da hier die Zeilenbegrenzung auf 65000 zuschlägt. Vielen Dank schon mal im vorraus für die Hilfe und einen Gruß aus Berlin Rolf-Hubert -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Rolf-Hubert Pobloth wrote:
Hallo Liste,
habe ein Frage an die MySQL Spezialisten, da ich mich damit nicht so sehr auskenne benötige ich bei folgendem Problem Eure Hilfe.
Datenbank hat 1 Tabelle mit 6 Spalten 1 Spalte ist der Primärschlüssel, d.h. pro Zeile ein Wert. Die gesamte Datei besteht nur aus rd. 470 000 Zeilen.
Okay, hier hast du mich schon abgehängt. Von welcher Datei redest du? Der MySQL-Datenbank, die physikalisch irgendwo liegt, oder von einer bisher nicht erwähnten Quelldatei, wo die Rohdaten im Textformat vorliegen, die jetzt in Datensätze und Felder getrennt und in die SQL-Datenbank importiert werden sollen? -- Sandy Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo Liste, Hallo Sandy, Am Dienstag, 30. Januar 2007 18:16 schrieb Sandy Drobic:
Rolf-Hubert Pobloth wrote:
Hallo Liste,
habe ein Frage an die MySQL Spezialisten, da ich mich damit nicht so sehr auskenne benötige ich bei folgendem Problem Eure Hilfe.
Datenbank hat 1 Tabelle mit 6 Spalten 1 Spalte ist der Primärschlüssel, d.h. pro Zeile ein Wert. Die gesamte Datei besteht nur aus rd. 470 000 Zeilen.
Es liegen die Daten einmal als Datei.csv vor, die aus einer ms.doc generiert wurde. Es sind rd. 16 000 Kundenkarten mit insgesammt 470 000 Zeilen. Die CSV-Datei habe ich mit knoda (phpadmin kann so große Dateien nicht verarbeiten) eingelesen und habe nun die TEST Datensatz Feld1 Feld2 Feld3 Feld4 Feld 5 und Feld6 MySQL Datenbank.
Okay, hier hast du mich schon abgehängt. Von welcher Datei redest du? Der MySQL-Datenbank, die physikalisch irgendwo liegt, oder von einer bisher nicht erwähnten Quelldatei, wo die Rohdaten im Textformat vorliegen, die jetzt in Datensätze und Felder getrennt und in die SQL-Datenbank importiert werden sollen? Sandy
Nach einer nochmaligen Überprüfung des Sachverhaltes bin ich auf folgenden Lösungsansatz gekommen, den ich leider aus Mangel an Programmierkenntnissen nicht umsetzen kann: Die DATEN.csv Datei beginnt wie folgt KUNDENKARTE;;;; also den Text KUNDENKARTE und 5 Semikolons (;) Feldtrenner. Wenn man diese Textdatei nun Satz für Satz lesen würde und beim Auftreten des KUNDENKARTE im selben Satz einen Zählerwert hinten anfügen würde und diese Datensätze (natürlich ALLE) in eine neue Datei schreibt, dann hätte ich das Problem gelöst. Die Zählervariable wird immer um 1 erhöht und somit entstehen rd. 16000 Zeilen mit einem aufsteigenden Zähler im Datensatz. Kann mir jemand vielleicht einen Shell-Script zur Lösung anbieten? Vielen Dank schon mal im vorraus Rolf-Hubert Beispiel Input-Datei KUNDENKARTE ; ; ; ; ; (CR-LF) Output-Datei KUNDENKARTE ; ; ; ; ; 0000001 (CR-LF) Dieses müsste doch mit einem kleine Bash-Programm zu lösen sein? -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
On Wednesday 31 January 2007 10:03, Rolf-Hubert Pobloth wrote:
Hallo Liste, Hallo Sandy,
Am Dienstag, 30. Januar 2007 18:16 schrieb Sandy Drobic:
Rolf-Hubert Pobloth wrote:
Hallo Liste,
habe ein Frage an die MySQL Spezialisten, da ich mich damit nicht so sehr auskenne benötige ich bei folgendem Problem Eure Hilfe.
Datenbank hat 1 Tabelle mit 6 Spalten 1 Spalte ist der Primärschlüssel, d.h. pro Zeile ein Wert. Die gesamte Datei besteht nur aus rd. 470 000 Zeilen.
Es liegen die Daten einmal als Datei.csv vor, die aus einer ms.doc generiert wurde. Es sind rd. 16 000 Kundenkarten mit insgesammt 470 000 Zeilen. Die CSV-Datei habe ich mit knoda (phpadmin kann so große Dateien nicht verarbeiten) eingelesen und habe nun die TEST Datensatz Feld1 Feld2 Feld3 Feld4 Feld 5 und Feld6 MySQL Datenbank.
das sollte doch mit einem einfachen SQL-Befehl machbar sein. Zuerst die SQL-Tabelle definieren und dabei auch eine AUTO-INCREMENT-Spalte einfügen (die dann jedem Datensatz eine automatische Nummer zuteilt). Dann die csv-Datei mit LOAD DATA INFILE importieren. Details über die zu verwendenden Parameter zu LOAD DATA gibts hier: http://dev.mysql.com/doc/refman/5.0/en/load-data.html (und per Suchmaschine sind sicher auch Beispiele auf Deutsch zu finden). Gruss Daniel -- Daniel Bauer photographer Basel Switzerland professional photography: http://www.daniel-bauer.com Madagascar special: http://www.sanic.ch -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Rolf-Hubert Pobloth wrote:
Es liegen die Daten einmal als Datei.csv vor, die aus einer ms.doc generiert wurde. Es sind rd. 16 000 Kundenkarten mit insgesammt 470 000 Zeilen. Die CSV-Datei habe ich mit knoda (phpadmin kann so große Dateien nicht verarbeiten) eingelesen und habe nun die TEST Datensatz Feld1 Feld2 Feld3 Feld4 Feld 5 und Feld6 MySQL Datenbank.
Ist das dann auch wirklich eine comma separated value Liste, keine weiteren Komma, die die Feldreihenfolge durcheinanderbringen können?
Okay, hier hast du mich schon abgehängt. Von welcher Datei redest du? Der MySQL-Datenbank, die physikalisch irgendwo liegt, oder von einer bisher nicht erwähnten Quelldatei, wo die Rohdaten im Textformat vorliegen, die jetzt in Datensätze und Felder getrennt und in die SQL-Datenbank importiert werden sollen? Sandy
Nach einer nochmaligen Überprüfung des Sachverhaltes bin ich auf folgenden Lösungsansatz gekommen, den ich leider aus Mangel an Programmierkenntnissen nicht umsetzen kann:
Die DATEN.csv Datei beginnt wie folgt
KUNDENKARTE;;;; also den Text KUNDENKARTE und 5 Semikolons (;) Feldtrenner. Wenn man diese Textdatei nun Satz für Satz lesen würde und beim Auftreten des KUNDENKARTE im selben Satz einen Zählerwert hinten anfügen würde und diese Datensätze (natürlich ALLE) in eine neue Datei schreibt, dann hätte ich das Problem gelöst.
Wieder so ein Schwammausdruck. (^-^) Was heißt "alle" hier. Bitte mal ein PRÄZISE Darstellung des Datensatzes. Das mit einem Shellscript/AWK/Perl zu machen, sollte nur ein paar Minuten dauern, aber das Herausfinden, was genau du brauchst, das scheint eine kleine Geduldaufgabe zu werden.
Die Zählervariable wird immer um 1 erhöht und somit entstehen rd. 16000 Zeilen mit einem aufsteigenden Zähler im Datensatz. Kann mir jemand vielleicht einen Shell-Script zur Lösung anbieten?
Nach bisherigem Verständnis würdest du eine Datei mit 16.000 Zeilen erhalten, die am Ende jeweils eine laufende Nummer erhalten. Ist das wirlich dein Ziel? Dann brauchst du die Quelldatei nicht, das kann ein Script auch so generieren.
Beispiel Input-Datei KUNDENKARTE ; ; ; ; ; (CR-LF) Output-Datei KUNDENKARTE ; ; ; ; ; 0000001 (CR-LF)
Dieses müsste doch mit einem kleine Bash-Programm zu lösen sein?
Bash/AWK/Perl, sind nur ein paar Zeilen. -- Sandy Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo Sandy, Am Mittwoch, 31. Januar 2007 11:53 schrieb Sandy Drobic:
Rolf-Hubert Pobloth wrote:
Es liegen die Daten einmal als Datei.csv vor, die aus einer ms.doc generiert wurde. Es sind rd. 16 000 Kundenkarten mit insgesammt 470 000 Zeilen. Die CSV-Datei habe ich mit knoda (phpadmin kann so große Dateien nicht verarbeiten) eingelesen und habe nun die TEST Datensatz Feld1 Feld2 Feld3 Feld4 Feld 5 und Feld6 MySQL Datenbank.
Ist das dann auch wirklich eine comma separated value Liste, keine weiteren Komma, die die Feldreihenfolge durcheinanderbringen können?
Okay, hier hast du mich schon abgehängt. Von welcher Datei redest du? Der MySQL-Datenbank, die physikalisch irgendwo liegt, oder von einer bisher nicht erwähnten Quelldatei, wo die Rohdaten im Textformat vorliegen, die jetzt in Datensätze und Felder getrennt und in die SQL-Datenbank importiert werden sollen? Sandy
Nach einer nochmaligen Überprüfung des Sachverhaltes bin ich auf folgenden Lösungsansatz gekommen, den ich leider aus Mangel an Programmierkenntnissen nicht umsetzen kann:
Die DATEN.csv Datei beginnt wie folgt
KUNDENKARTE;;;; also den Text KUNDENKARTE und 5 Semikolons (;) Feldtrenner. Wenn man diese Textdatei nun Satz für Satz lesen würde und beim Auftreten des KUNDENKARTE im selben Satz einen Zählerwert hinten anfügen würde und diese Datensätze (natürlich ALLE) in eine neue Datei schreibt, dann hätte ich das Problem gelöst.
Wieder so ein Schwammausdruck. (^-^) Was heißt "alle" hier. Bitte mal ein PRÄZISE Darstellung des Datensatzes. Das mit einem Shellscript/AWK/Perl zu machen, sollte nur ein paar Minuten dauern, aber das Herausfinden, was genau du brauchst, das scheint eine kleine Geduldaufgabe zu werden. Tschuldigung für diesen unpräziesen Ansatz.
1. Es ist eine Komma-Separierte-Datei, wobei das Trennzeichen der Spalten ein Semikolon ist AAAAA;BBBBB;CCCCC, Läßt sich auch unter MySQL als csv Datei einlesen.
Die Zählervariable wird immer um 1 erhöht und somit entstehen rd. 16000 Zeilen mit einem aufsteigenden Zähler im Datensatz. Kann mir jemand vielleicht einen Shell-Script zur Lösung anbieten?
Nach bisherigem Verständnis würdest du eine Datei mit 16.000 Zeilen erhalten, die am Ende jeweils eine laufende Nummer erhalten. Ist das wirlich dein Ziel? Dann brauchst du die Quelldatei nicht, das kann ein Script auch so generieren. Nein, so sollte es nicht sein.
Der erste Datensatz hat im Feld1 den Wert KUNDENKARTE und nur in diesem Datensatz soll im neuen Feld7 der Wert mit 000001 beginnen. Die nachfolgenden Zeilen werden ebenfalls im Feld7 nit dem Wert 00001 beschrieben(append).Wenn dann der Datensatz 80 im Feld 1 den Wert KUNDENKARTE hat, soll der Zähler 000002 in das Feld7geschrieben werden bis der nächste Datensatz im Feld1 sich auf KUNDENKARTE ändert.. Quelle: Datei.csv KUNDENKARTE;;; (Feld2 bis Feld 6 sind IMMER leer) Textzeile Textzeile und dann z.B bei Zeile 80 kommt wieder KUNDENKARTE;;;;;; Ziel: Datei1.csv KUNDENKARTE;;;;;00001 Textzeile 2 - 79 haben im Feld7 ebenfalls den Zählerwert 00001 KUNDENKARTE;;;;;00002 Textzeile 81 - 133 haben im Feld7 ebenfalls den Zählerwert 00002 usw bis zum Ende der Dateien Nach dieser Satzverlängerung in der Zieldatei.csv kann ich diese dann mit MySQL in die Datenbank einlesen. In der Datenbank sind dann im Feld 7 alle zusammen gehörenden Datensätze (KUNDENKARTE) mit einer eindeutigen Zahl im Feld7 gekennzeichnet. Hoffentlich habe ich des Problem nun verständlicher beschrieben.
Beispiel Input-Datei KUNDENKARTE ; ; ; ; ; (CR-LF) Output-Datei KUNDENKARTE ; ; ; ; ; 0000001 (CR-LF)
Dieses müsste doch mit einem kleine Bash-Programm zu lösen sein?
Bash/AWK/Perl, sind nur ein paar Zeilen. Das scheint mir auch am sinnvollsten zu sein ehe ich irgendwelche Verrenkungen bei MySQL mache. Die Dateien sind ja auch nicht gerade klein. Sandy
Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com
Vielen Dank für die bisherige Hilfe Rolf-Hubert -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Rolf-Hubert Pobloth wrote:
Der erste Datensatz hat im Feld1 den Wert KUNDENKARTE und nur in diesem Datensatz soll im neuen Feld7 der Wert mit 000001 beginnen. Die nachfolgenden Zeilen werden ebenfalls im Feld7 nit dem Wert 00001 beschrieben(append).Wenn dann der Datensatz 80 im Feld 1 den Wert KUNDENKARTE hat, soll der Zähler 000002 in das Feld7geschrieben werden bis der nächste Datensatz im Feld1 sich auf KUNDENKARTE ändert..
Quelle: Datei.csv
KUNDENKARTE;;; (Feld2 bis Feld 6 sind IMMER leer) Textzeile Textzeile und dann z.B bei Zeile 80 kommt wieder KUNDENKARTE;;;;;;
Ziel: Datei1.csv
KUNDENKARTE;;;;;00001 Textzeile 2 - 79 haben im Feld7 ebenfalls den Zählerwert 00001 KUNDENKARTE;;;;;00002 Textzeile 81 - 133 haben im Feld7 ebenfalls den Zählerwert 00002 usw bis zum Ende der Dateien
/tmp/datei.csv: KUNDENKARTE;;;;; zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6; zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6; KUNDENKARTE;;;;; zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6; zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6; /tmp/insertcounter.sh: counter=0 cat /tmp/datei.csv| while read line do firstfield=`echo $line| awk -F\; '{print $1}'` if [ $firstfield = KUNDENKARTE ] ; then { counter=`expr $counter + 1` echo $line| awk -F\; "{print \$1 \";\" \$2 \";\" \$3 \";\" \$4 \";\" \$5 \";\" \$6 \";\" $counter}" } else echo $line| awk -F\; "{print \$1 \";\" \$2 \";\" \$3 \";\" \$4 \";\" \$5 \";\" \$6 \";\" $counter}" fi done Die awk-Zeilen sind eine einzige Zeile, ist leider durch die Mail umgebrochen. Ausgabe: # /tmp/insertcounter.sh KUNDENKARTE;;;;;;1 zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6;1 zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6;1 KUNDENKARTE;;;;;;2 zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6;2 zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6;2 Das kann man noch etwas sauber machen, aber für eine einmalige Gelegenheit reicht es. Wenn das das gewünschte Ergebnis ist, dann musst du die Ausgabe des Scriptes nur noch ein eine Datei lenken. Sandy -- Sandy Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
Rolf-Hubert Pobloth wrote: [..] /tmp/datei.csv: KUNDENKARTE;;;;; zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6; zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6; KUNDENKARTE;;;;; zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6; zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6;
/tmp/insertcounter.sh: [..] counter=0 cat /tmp/datei.csv| while read line do [..] done
*uargs* Sorry Sandy, aber das ist ganz übel... *SCNR* $ awk 'BEGIN { FS=";"; OFS=";"; } /KUNDENKARTE/{ cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv KUNDENKARTE;;;;;;000001 zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6;000001 zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6;000001 KUNDENKARTE;;;;;;000002 zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6;000002 zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6;000002 Beim 'cnt++' bin ich mir nicht sicher, ob das portabel ist, garantiert gehen würde: /KUNDENKARTE/{ cnt = cnt + 1; } oder auch (meist?) /KUNDENKARTE/{ cnt += 1; } Im Standard http://www.opengroup.org/onlinepubs/007908799/xcu/awk.html sind alle drei Varianten drin und mit GNU awk -W traditional etc. bekomme ich keine Warnungen. Es sollte also auch 'cnt++' portabel sein. -dnh -- 274: Nikoma-Newsserver Museum für prähistorische Gruppen. (Ulrich Mindrup) -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
David Haller wrote:
Hallo,
Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
Rolf-Hubert Pobloth wrote: [..] /tmp/datei.csv: KUNDENKARTE;;;;; zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6; zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6; KUNDENKARTE;;;;; zeile1-f1;zeile1-f2;zeile1-f3;zeile1-f4;zeile1-f5;zeile1-f6; zeile2-f1;zeile2-f2;zeile2-f3;zeile2-f4;zeile2-f5;zeile2-f6;
/tmp/insertcounter.sh: [..] counter=0 cat /tmp/datei.csv| while read line do [..] done
*uargs* Sorry Sandy, aber das ist ganz übel... *SCNR*
Grins! Verübeln tue ich es dir nicht. (^-°) Aber für "mal eben schnell in der Mittagspause hinschreiben" hat es mir gereicht. Bis ich die Optionen für AWK alle zusammengesucht hätte, wäre das umständlichere Script schon durchgelaufen.
$ awk 'BEGIN { FS=";"; OFS=";"; } /KUNDENKARTE/{ cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
Ich nehme mir schon die ganze Zeit vor, diese Textwerkzeuge einmal eine Woche lang durchzuackern, aber es kommt immer eine andere Sache, die höhere Priorität hat. :-/
Im Standard http://www.opengroup.org/onlinepubs/007908799/xcu/awk.html sind alle drei Varianten drin und mit GNU awk -W traditional etc. bekomme ich keine Warnungen. Es sollte also auch 'cnt++' portabel sein.
Da ich nicht viele Oldtimer unter meinen Systemen habe, sollte es auch mit cnt++ gehen. Den Linke jedenfalls habe ich mir notiert, das geht etwas schneller als sich die Optionen über "man awk" zusammenzusuchen. -- Sandy Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
David Haller wrote:
Am Mit, 31 Jan 2007, Sandy Drobic schrieb: [Loesung mit shell + awk in Schleife] *uargs* Sorry Sandy, aber das ist ganz übel... *SCNR*
Grins! Verübeln tue ich es dir nicht. (^-°)
*g* Du hast halt das, was awk am besten kann, mehr oder weniger gut mit der shell gemacht. Wenn du das raussuchen der Felder etc. auch noch mit shell-Mitteln gemacht hättest, hätt's kein "uargs" gegeben (nur den Hinweis, daß es mit awk vielleicht einfacher ist). Hier ne Bash Lösung: ==== #!/bin/bash declare -a A cnt=0 while read line; do IFS=";" A=( $line ) if test "x${A[0]}" = "xKUNDENKARTE"; then cnt=$(( cnt + 1 )) A[5]='' ## irgendwie wird ein Feld gefressen, und ohne das ## hier landet $cnt in Feld 6 fi printf "%s;%s;%s;%s;%s;%s;%06i\n" "${A[@]}" $cnt done ==== BTW: ja, das ist verwendet "Bashismen" ;) Speziell der Trick mit dem Aufspalten (an $IFS) ins Array ist bash-spezifisch. Traditionell geht's aber auch (read f1 f2 .. f6, ich bekomme hier aber gerade immer ein ';' zuviel oder hinter "KUNDENKARTE" ein leeres Feld zuwenig (s.o.)). Deswegen jetzt keine Lösung nur mit bourne-shell Mitteln.
Aber für "mal eben schnell in der Mittagspause hinschreiben" hat es mir gereicht. Bis ich die Optionen für AWK alle zusammengesucht hätte, wäre das umständlichere Script schon durchgelaufen.
*g* Ja, kann ich verstehen.
$ awk 'BEGIN { FS=";"; OFS=";"; } /KUNDENKARTE/{ cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
BTW: das ist noch "faslch"! Richtigerweise ist ja gefordert, das wenn das Feld 1 = "KUNDENKARTE" ist, dann ... Korrekt ist also: awk 'BEGIN { FS=";"; OFS=";"; } $1 == "KUNDENKARTE" { cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv Ggfs. kann man die Bedingung natürlich auch anders (z.B. als Regex) formulieren, was aber nur sinnvoll ist, wenn das Feld z.B. nur mit KUNDENKARTE beginnen muß, aber vor dem ';' noch weiteres enthalten könnte. Das könnte man dann so machen: awk 'BEGIN { FS=";"; OFS=";"; } $1 ~ /^KUNDENKARTE/ { cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv Da würde cnt auch erhöht, wenn im ersten Feld z.B. KUNDENKARTE_MIT_RABATT stehen würde (oder sonstwas, auf das die RE eben passt ;)
Ich nehme mir schon die ganze Zeit vor, diese Textwerkzeuge einmal eine Woche lang durchzuackern, aber es kommt immer eine andere Sache, die höhere Priorität hat. :-/
*g* Wobei das, was ich verwendet habe (FS entspricht der Option '-F' auf der Kommandozeile, und OFS ist das Gegenstück für die Ausgabe, in der manpage nicht gerade schwer zu finden ;) sind eigentlich grundlegende Dinge bei awk. Was man schon daran sieht, daß ich ohne GNU awk Erweiterungen auskomme ;) Und es sind ja nur 3 Muster + Block: Muster: BEGIN # wird zum Script-start ausgeführt Block: Setze FS und OFS jew. auf ';' (Option -F';' setzt FS=";") Muster: $1 == "KUNDENKARTE" # Feld 1 ist der String in "" Block: { cnt++; } # addiere 1 zu cnt Muster: <keins> # passt auf jede Zeile (=> Siehe auch # Variable RS / Record-Seperator) Block: - Feld 7 per sprintf setzen - Ausgabe per print, Details siehe Doku (insbesondere, daß die Felder mit dem ersten Zeichen aus OFS zusammengepappt werden. Und die jew. print werden mittels ORS zusammengepappt). Dafür muß man nicht viel mehr, als einmal die manpage durcharbeiten (kein Vorwurf!). Der Algorithmus ist jeweils der, den du schon bei deiner Lösung verwendet hast. Und die awk-Lösung ist eben einfach ;)
Im Standard http://www.opengroup.org/onlinepubs/007908799/xcu/awk.html sind alle drei Varianten drin und mit GNU awk -W traditional etc. bekomme ich keine Warnungen. Es sollte also auch 'cnt++' portabel sein.
Da ich nicht viele Oldtimer unter meinen Systemen habe, sollte es auch mit cnt++ gehen. Den Linke jedenfalls habe ich mir notiert, das geht etwas schneller als sich die Optionen über "man awk" zusammenzusuchen.
Hä? Das sind doch praktisch die Manpages, nur eben in der Version, die dem Standard entspricht bzw. diesen definiert ;) Aber wie gesagt: die Operatoren ++ <als PREFIX> und <als POSTFIX> ++ scheinen von Anfang an bei awk dabeigewesen zu sein. Ob's (ältere, exotischere) Implementationen gibt, die das nicht implementieren weiß ich nicht. Vergleiche dagegen mal die Features von http://www.opengroup.org/onlinepubs/007908799/xcu/find.html mit denen der GNU find Variante... (Mist, das ist alles SUSv2, aktuell ist SUSv3, da ist dann bei find IIRC z.B. das '-exec ... {} +' definiert, das es bei GNU find nicht gibt... Ah, halt, da: http://www.unix.org/version3/ gibt's wohl die aktuelle Version, da muß man sich aber registrieren (weiter hab ich jetzt nicht geschaut) :)) Die Experten (speziell zu Standards und Portabilität) sind z.B. in de.comp.os.unix.shell zu finden ;) Aber mit so Details würde ich mich an deiner Stelle noch nicht befassen. Wenn's in einer Man/Infopage Abschnitte mit einem Titel wie "CONFORMING TO", "POSIX COMPATIBILITY", "GNU EXTENSIONS" o.ä. gibt, dann sollte man sich den durchlesen und sich ungefähr merken, welche Features betroffen sind... Speziell jemand wie du, der auch (mal) unter anderen (und älteren) Unices hantiert ;) BTW: ein Script, das unter der 'ash' läuft, kann man AFAIK als Bourne-kompatibel (d.h. portabel) ansehen. Aber ein explizites(!) (d.h. mit "#!/bin/bash" deklariertes) Bash-script ist manchmal sinnvoll(er) *g*. -dnh PS: melde dich ruhig auch mal per PM ;) -- D: is just a data disk. That's why it's called "D", for "DATA". C: is the Windows OS disk, so it's called "C", for "CRAP". -- David P. Murphy -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
David Haller wrote:
Hallo,
Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
David Haller wrote:
Am Mit, 31 Jan 2007, Sandy Drobic schrieb: [Loesung mit shell + awk in Schleife] *uargs* Sorry Sandy, aber das ist ganz übel... *SCNR* Grins! Verübeln tue ich es dir nicht. (^-°)
*g* Du hast halt das, was awk am besten kann, mehr oder weniger gut mit der shell gemacht. Wenn du das raussuchen der Felder etc. auch noch mit shell-Mitteln gemacht hättest, hätt's kein "uargs" gegeben (nur den Hinweis, daß es mit awk vielleicht einfacher ist). Hier ne
Ich habe ohne "man awk" und "man bash" gearbeitet, eben "mal schnell geschrieben". Hauptsache war, dass es zuverlässig und transparent funktioniert. Für ständig wiederkehrende Scripte würde ich in der Tat etwas mehr Aufwand reinstecken, aber da lohnt es sich dann auch.
Bash Lösung:
==== #!/bin/bash declare -a A cnt=0 while read line; do IFS=";" A=( $line ) if test "x${A[0]}" = "xKUNDENKARTE"; then cnt=$(( cnt + 1 )) A[5]='' ## irgendwie wird ein Feld gefressen, und ohne das ## hier landet $cnt in Feld 6
fi printf "%s;%s;%s;%s;%s;%s;%06i\n" "${A[@]}" $cnt done ====
Komisch, das mit dem Feld gefressen. Na ja, vielleicht mal am Wochenende. (^-^)
BTW: ja, das ist verwendet "Bashismen" ;) Speziell der Trick mit dem Aufspalten (an $IFS) ins Array ist bash-spezifisch.
Solange wir unter Suse sind, ist das kein Problem. Nur bei Kunden bzw. als allgemeines unabhängiges Script sollte man das wirklich im Auge behalten. In dem Zusammenhang ein dickes Lob, dass du so präzise darauf hinweist!
Aber für "mal eben schnell in der Mittagspause hinschreiben" hat es mir gereicht. Bis ich die Optionen für AWK alle zusammengesucht hätte, wäre das umständlichere Script schon durchgelaufen.
*g* Ja, kann ich verstehen.
$ awk 'BEGIN { FS=";"; OFS=";"; } /KUNDENKARTE/{ cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
BTW: das ist noch "faslch"! Richtigerweise ist ja gefordert, das wenn das Feld 1 = "KUNDENKARTE" ist, dann ... Korrekt ist also:
awk 'BEGIN { FS=";"; OFS=";"; } $1 == "KUNDENKARTE" { cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
Ggfs. kann man die Bedingung natürlich auch anders (z.B. als Regex) formulieren, was aber nur sinnvoll ist, wenn das Feld z.B. nur mit KUNDENKARTE beginnen muß, aber vor dem ';' noch weiteres enthalten könnte. Das könnte man dann so machen:
Wenn man sieht, was alles mit AWK möglich ist, dann kribbelt es einem in den Fingern, sich darin einzuarbeiten. Gestern hatte ich aber erheblich mehr mit meiner Internet-Leitung zu tun und musste zunächst wieder auf meine dynamische Leitung zurückgreifen. Hoffentlich bekommt QSC das Problem heute in den Griff, dann kann ich heute abend wieder zurückschalten.
Und es sind ja nur 3 Muster + Block:
Muster: BEGIN # wird zum Script-start ausgeführt Block: Setze FS und OFS jew. auf ';' (Option -F';' setzt FS=";")
Muster: $1 == "KUNDENKARTE" # Feld 1 ist der String in "" Block: { cnt++; } # addiere 1 zu cnt
Muster: <keins> # passt auf jede Zeile (=> Siehe auch # Variable RS / Record-Seperator) Block: - Feld 7 per sprintf setzen - Ausgabe per print, Details siehe Doku (insbesondere, daß die Felder mit dem ersten Zeichen aus OFS zusammengepappt werden. Und die jew. print werden mittels ORS zusammengepappt).
Dafür muß man nicht viel mehr, als einmal die manpage durcharbeiten (kein Vorwurf!).
Diese Zeit hatte ich mir genau nicht genommen. Sonst hätte ich noch einmal nachschauen müssen, wie die Parameter für printf, AWK, die präzise Syntax für AWK lautet etc. Die Mittagspause musste auch noch fürs Magenfüllen herhalten. (^-^)
Der Algorithmus ist jeweils der, den du schon bei deiner Lösung verwendet hast. Und die awk-Lösung ist eben einfach ;)
Nur im adleräugigen Rückblick! Bis man dies erst erstellt hat, ist der Weg nicht so einfach. Einfach ist es erst, wenn man die Syntax sich erarbeitet hat und einige kleine Kniffe kennt.
Im Standard http://www.opengroup.org/onlinepubs/007908799/xcu/awk.html sind alle drei Varianten drin und mit GNU awk -W traditional etc. bekomme ich keine Warnungen. Es sollte also auch 'cnt++' portabel sein. Da ich nicht viele Oldtimer unter meinen Systemen habe, sollte es auch mit cnt++ gehen. Den Linke jedenfalls habe ich mir notiert, das geht etwas schneller als sich die Optionen über "man awk" zusammenzusuchen.
Hä? Das sind doch praktisch die Manpages, nur eben in der Version, die dem Standard entspricht bzw. diesen definiert ;)
Wenn ich auf der Shell arbeite (nicht Linux als Desktop-System!), dann ist die man page recht mühselig. Da ist es wirklich einfacher, die HTML-Seite nebenher aufzumachen.
PS: melde dich ruhig auch mal per PM ;)
Mache ich, wenn ich wieder auf der statischen Leitung bin. (^-^) -- Sandy Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo Sandy, Hallo David, vielen Dank für die ausführliche Diskussion, die meine kleine Problemanfrage ausgelöst hat. Leider kann ich aus den ganzen Codeschnipseln kein lauffähigen Script hinbekommen. Wäre es zuviel verlangt, mir einen Script komplett zu erstellen, mit dem ich meine Daten umstellen kann. Input-Datei ist datei.csv Output soll sein datei1.csv Der Schlüsselbegriff ist KUNDENKARTE Vielen Dank schon mal im vorraus Rolf-Hubert Am Donnerstag, 1. Februar 2007 11:58 schrieb Sandy Drobic:
David Haller wrote:
Hallo,
Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
David Haller wrote:
Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
[Loesung mit shell + awk in Schleife]
*uargs* Sorry Sandy, aber das ist ganz übel... *SCNR*
Grins! Verübeln tue ich es dir nicht. (^-°)
*g* Du hast halt das, was awk am besten kann, mehr oder weniger gut mit der shell gemacht. Wenn du das raussuchen der Felder etc. auch noch mit shell-Mitteln gemacht hättest, hätt's kein "uargs" gegeben (nur den Hinweis, daß es mit awk vielleicht einfacher ist). Hier ne
Ich habe ohne "man awk" und "man bash" gearbeitet, eben "mal schnell geschrieben". Hauptsache war, dass es zuverlässig und transparent funktioniert.
Für ständig wiederkehrende Scripte würde ich in der Tat etwas mehr Aufwand reinstecken, aber da lohnt es sich dann auch.
Bash Lösung:
==== #!/bin/bash declare -a A cnt=0 while read line; do IFS=";" A=( $line ) if test "x${A[0]}" = "xKUNDENKARTE"; then cnt=$(( cnt + 1 )) A[5]='' ## irgendwie wird ein Feld gefressen, und ohne das ## hier landet $cnt in Feld 6
fi printf "%s;%s;%s;%s;%s;%s;%06i\n" "${A[@]}" $cnt done ====
Dieser Script ist nicht komplett???? es kommt eine Fehlermeldung in der Zeile A=($line)
Komisch, das mit dem Feld gefressen. Na ja, vielleicht mal am Wochenende. (^-^)
BTW: ja, das ist verwendet "Bashismen" ;) Speziell der Trick mit dem Aufspalten (an $IFS) ins Array ist bash-spezifisch.
Solange wir unter Suse sind, ist das kein Problem. Nur bei Kunden bzw. als allgemeines unabhängiges Script sollte man das wirklich im Auge behalten. In dem Zusammenhang ein dickes Lob, dass du so präzise darauf hinweist!
Aber für "mal eben schnell in der Mittagspause hinschreiben" hat es mir gereicht. Bis ich die Optionen für AWK alle zusammengesucht hätte, wäre das umständlichere Script schon durchgelaufen.
*g* Ja, kann ich verstehen.
$ awk 'BEGIN { FS=";"; OFS=";"; } /KUNDENKARTE/{ cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
BTW: das ist noch "faslch"! Richtigerweise ist ja gefordert, das wenn das Feld 1 = "KUNDENKARTE" ist, dann ... Korrekt ist also:
awk 'BEGIN { FS=";"; OFS=";"; } $1 == "KUNDENKARTE" { cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
Ggfs. kann man die Bedingung natürlich auch anders (z.B. als Regex) formulieren, was aber nur sinnvoll ist, wenn das Feld z.B. nur mit KUNDENKARTE beginnen muß, aber vor dem ';' noch weiteres enthalten könnte. Das könnte man dann so machen:
Wenn man sieht, was alles mit AWK möglich ist, dann kribbelt es einem in den Fingern, sich darin einzuarbeiten. Gestern hatte ich aber erheblich mehr mit meiner Internet-Leitung zu tun und musste zunächst wieder auf meine dynamische Leitung zurückgreifen. Hoffentlich bekommt QSC das Problem heute in den Griff, dann kann ich heute abend wieder zurückschalten.
Und es sind ja nur 3 Muster + Block:
Muster: BEGIN # wird zum Script-start ausgeführt Block: Setze FS und OFS jew. auf ';' (Option -F';' setzt FS=";")
Muster: $1 == "KUNDENKARTE" # Feld 1 ist der String in "" Block: { cnt++; } # addiere 1 zu cnt
Muster: <keins> # passt auf jede Zeile (=> Siehe auch # Variable RS / Record-Seperator) Block: - Feld 7 per sprintf setzen - Ausgabe per print, Details siehe Doku (insbesondere, daß die Felder mit dem ersten Zeichen aus OFS zusammengepappt werden. Und die jew. print werden mittels ORS zusammengepappt).
Dafür muß man nicht viel mehr, als einmal die manpage durcharbeiten (kein Vorwurf!).
Diese Zeit hatte ich mir genau nicht genommen. Sonst hätte ich noch einmal nachschauen müssen, wie die Parameter für printf, AWK, die präzise Syntax für AWK lautet etc. Die Mittagspause musste auch noch fürs Magenfüllen herhalten. (^-^)
Der Algorithmus ist jeweils der, den du schon bei deiner Lösung verwendet hast. Und die awk-Lösung ist eben einfach ;)
Nur im adleräugigen Rückblick! Bis man dies erst erstellt hat, ist der Weg nicht so einfach. Einfach ist es erst, wenn man die Syntax sich erarbeitet hat und einige kleine Kniffe kennt.
Im Standard http://www.opengroup.org/onlinepubs/007908799/xcu/awk.html sind alle drei Varianten drin und mit GNU awk -W traditional etc. bekomme ich keine Warnungen. Es sollte also auch 'cnt++' portabel sein.
Da ich nicht viele Oldtimer unter meinen Systemen habe, sollte es auch mit cnt++ gehen. Den Linke jedenfalls habe ich mir notiert, das geht etwas schneller als sich die Optionen über "man awk" zusammenzusuchen.
Hä? Das sind doch praktisch die Manpages, nur eben in der Version, die dem Standard entspricht bzw. diesen definiert ;)
Wenn ich auf der Shell arbeite (nicht Linux als Desktop-System!), dann ist die man page recht mühselig. Da ist es wirklich einfacher, die HTML-Seite nebenher aufzumachen.
PS: melde dich ruhig auch mal per PM ;)
Mache ich, wenn ich wieder auf der statischen Leitung bin. (^-^)
-- Sandy
Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, Am Don, 01 Feb 2007, Rolf-Hubert Pobloth schrieb:
Wäre es zuviel verlangt, mir einen Script komplett zu erstellen, mit dem ich meine Daten umstellen kann.
Input-Datei ist datei.csv Output soll sein datei1.csv Der Schlüsselbegriff ist KUNDENKARTE Vielen Dank schon mal im vorraus
Es ist komplett. awk 'BEGIN { FS=";"; OFS=";"; } $1 == "KUNDENKARTE" { cnt++; } { $7 = sprintf("%06i", cnt); print; }' datei.csv > datei1.csv [..]
David Haller wrote: [meine bash-Loesung]
Dieser Script ist nicht komplett???? es kommt eine Fehlermeldung in der Zeile A=($line)
Bei mir nicht. $ bash --version GNU bash, version 2.03.0(1)-release (i386-suse-linux) Copyright 1998 Free Software Foundation, Inc. -dnh --
BUCH stürzt niemals ab, muss auch nicht neu gebootet werden, [...] Sorry, hier muss ich widersprechen: Bei mir *stürzten* bereits mehrere Versionen von BUCH ab, aber nach einem Reset - in dieser Technologie wohl BUECKEN genannt - konnte es wieder genutzt werden... -- Mike Mueller -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo Liste, Hallo Sandy, Hallo David, vielen Dank für Eure Unterstützung bei der Lösung meines Problems. Da bei mir leider die awk -Lösung nicht lief, warum auch immer, habe ich bei Self-HTML mir einen 'Perl-Script ´ entliehen und nach meinen Wünschen umgestrickt. In der Quell-Datei habe ich die Zeile KUNDENKARTE mit suchen und ersetzen mit dem Editor Kate das Wort KUNDENKARTE in einen Zahlenwert, hier 100000, gewandelt um eine für leichtere if Abfrage zu erreichen. Am Donnerstag, 1. Februar 2007 20:28 schrieb David Haller:
Hallo,
Am Don, 01 Feb 2007, Rolf-Hubert Pobloth schrieb:
Wäre es zuviel verlangt, mir einen Script komplett zu erstellen, mit dem ich meine Daten umstellen kann.
Input-Datei ist datei.csv Output soll sein datei1.csv Der Schlüsselbegriff ist KUNDENKARTE Vielen Dank schon mal im vorraus
Es ist komplett.
awk 'BEGIN { FS=";"; OFS=";"; } $1 == "KUNDENKARTE" { cnt++; } { $7 = sprintf("%06i", cnt); print; }' datei.csv > datei1.csv
[..]
David Haller wrote:
[meine bash-Loesung]
Dieser Script ist nicht komplett???? es kommt eine Fehlermeldung in der Zeile A=($line)
Bei mir nicht.
$ bash --version GNU bash, version 2.03.0(1)-release (i386-suse-linux) Copyright 1998 Free Software Foundation, Inc.
-dnh
--
BUCH stürzt niemals ab, muss auch nicht neu gebootet werden, [...]
Sorry, hier muss ich widersprechen: Bei mir *stürzten* bereits mehrere Versionen von BUCH ab, aber nach einem Reset - in dieser Technologie wohl BUECKEN genannt - konnte es wieder genutzt werden... -- Mike Mueller
Um für alle in der Liste meine Lösung zu zeigen, habe ich den Script hier eingefügt. --------------------------------------------------------------------- #!/usr/bin/perl # Dieses Beispiel liest eine kommabegrenzte Datei mit Adressen ein # und schreibt sie HTML-formatiert in eine neue Datei # Dieser Script ist von SelfHTML als Muster genommen worden. # Daher auch die Namen wie Adressen und HTML Datei. @Adressen = (""); # Speicher für alle Datensaetze @Datensatz = (""); # Speicher für alle Felder des aktuellen Datensatzes $Felder = ""; # Speicher für die Namen der Felder (stehen in der ersten Dateizeile $i = 0; # Zeilenzähler $k = 0; # Key-Zähler $t = ";" ; # Feldtrenner open(ADRESSEN, "<datei0.csv") || die "Adressendatei nicht gefunden\n"; while(<ADRESSEN>) # Kommabegrenzte Datei einlesen { if($i == 0) # erste Zeile der Datei einlesen { $Felder = $_; # Feldnamen ermitteln } else { $Adressen[$i] = $_; # ab zweiter Zeile in @Adressen einlesen } $i++; # Datensatzzähler erhöhen } close(ADRESSEN); $Anzahl = $i - 1; # Anzahl Datensätze merken chop($Felder); @Datenfelder = split(/,/,$Felder); # Erste Zeile mit Feldnamen aufdröseln open(ADRESSENDAT, ">datei2.csv"); # HTML-Datei zum Schreiben öffnen for(@Adressen) # solange Daten in der Adressenliste sind { @Datensatz = split(/,/,$_); # Aktuellen Datensatz aufdröseln $i = 0; for(@Datensatz) { $text = $Datensatz[$i]; # Den aktuellen Datensatz in die Abfrage-Variable kopieren if ($text == 100000) # Die "KUNDENKARTE";;;;;; Zeile in der Quelle vorher mit suchen und ersetzen # in eine Zahl gewandelt um eine eindeutige if Abfrage zu erreichen. { $k++; # Nur bei 100000 soll der Zähler um 1 erhöht werden } print $k . $t . $Datensatz[$i] ; # Nur Bildschirmausgabe, um die Daten zu prüfen print ADRESSENDAT $k . $t . $Datensatz[$i] ; # Aktuellen Datensatz schreiben $i++; } } close(ADRESSENDAT); print $Anzahl," Datensaetze geschrieben\n"; # Nur zur Kontrolle: auf Standardausgabe ---------------------------------------------------------------------------------------------- Mit einem freundlichen Gruß aus Berlin Rolf-Hubert -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo Sandy, Hallo David, vielen Dank für die ausführliche Diskussion, die meine kleine Problemanfrage ausgelöst hat. Leider kann ich aus den ganzen Codeschnipseln kein lauffähigen Script hinbekommen. Wäre es zuviel verlangt, mir einen Script komplett zu erstellen, mit dem ich meine Daten umstellen kann. Input-Datei ist datei.csv Output soll sein datei1.csv Der Schlüsselbegriff ist KUNDENKARTE Vielen Dank schon mal im vorraus Rolf-Hubert Am Donnerstag, 1. Februar 2007 11:58 schrieb Sandy Drobic:
David Haller wrote:
Hallo,
Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
David Haller wrote:
Am Mit, 31 Jan 2007, Sandy Drobic schrieb:
[Loesung mit shell + awk in Schleife]
*uargs* Sorry Sandy, aber das ist ganz übel... *SCNR*
Grins! Verübeln tue ich es dir nicht. (^-°)
*g* Du hast halt das, was awk am besten kann, mehr oder weniger gut mit der shell gemacht. Wenn du das raussuchen der Felder etc. auch noch mit shell-Mitteln gemacht hättest, hätt's kein "uargs" gegeben (nur den Hinweis, daß es mit awk vielleicht einfacher ist). Hier ne
Ich habe ohne "man awk" und "man bash" gearbeitet, eben "mal schnell geschrieben". Hauptsache war, dass es zuverlässig und transparent funktioniert.
Für ständig wiederkehrende Scripte würde ich in der Tat etwas mehr Aufwand reinstecken, aber da lohnt es sich dann auch.
Bash Lösung:
==== #!/bin/bash declare -a A cnt=0 while read line; do IFS=";" A=( $line ) if test "x${A[0]}" = "xKUNDENKARTE"; then cnt=$(( cnt + 1 )) A[5]='' ## irgendwie wird ein Feld gefressen, und ohne das ## hier landet $cnt in Feld 6
fi printf "%s;%s;%s;%s;%s;%s;%06i\n" "${A[@]}" $cnt done ====
Dieser Script ist nicht komplett???? es kommt eine Fehlermeldung in der Zeile A=($line)
Komisch, das mit dem Feld gefressen. Na ja, vielleicht mal am Wochenende. (^-^)
BTW: ja, das ist verwendet "Bashismen" ;) Speziell der Trick mit dem Aufspalten (an $IFS) ins Array ist bash-spezifisch.
Solange wir unter Suse sind, ist das kein Problem. Nur bei Kunden bzw. als allgemeines unabhängiges Script sollte man das wirklich im Auge behalten. In dem Zusammenhang ein dickes Lob, dass du so präzise darauf hinweist!
Aber für "mal eben schnell in der Mittagspause hinschreiben" hat es mir gereicht. Bis ich die Optionen für AWK alle zusammengesucht hätte, wäre das umständlichere Script schon durchgelaufen.
*g* Ja, kann ich verstehen.
$ awk 'BEGIN { FS=";"; OFS=";"; } /KUNDENKARTE/{ cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
BTW: das ist noch "faslch"! Richtigerweise ist ja gefordert, das wenn das Feld 1 = "KUNDENKARTE" ist, dann ... Korrekt ist also:
awk 'BEGIN { FS=";"; OFS=";"; } $1 == "KUNDENKARTE" { cnt++; } { $7 = sprintf("%06i", cnt); print; }' /tmp/datei.csv
Ggfs. kann man die Bedingung natürlich auch anders (z.B. als Regex) formulieren, was aber nur sinnvoll ist, wenn das Feld z.B. nur mit KUNDENKARTE beginnen muß, aber vor dem ';' noch weiteres enthalten könnte. Das könnte man dann so machen:
Wenn man sieht, was alles mit AWK möglich ist, dann kribbelt es einem in den Fingern, sich darin einzuarbeiten. Gestern hatte ich aber erheblich mehr mit meiner Internet-Leitung zu tun und musste zunächst wieder auf meine dynamische Leitung zurückgreifen. Hoffentlich bekommt QSC das Problem heute in den Griff, dann kann ich heute abend wieder zurückschalten.
Und es sind ja nur 3 Muster + Block:
Muster: BEGIN # wird zum Script-start ausgeführt Block: Setze FS und OFS jew. auf ';' (Option -F';' setzt FS=";")
Muster: $1 == "KUNDENKARTE" # Feld 1 ist der String in "" Block: { cnt++; } # addiere 1 zu cnt
Muster: <keins> # passt auf jede Zeile (=> Siehe auch # Variable RS / Record-Seperator) Block: - Feld 7 per sprintf setzen - Ausgabe per print, Details siehe Doku (insbesondere, daß die Felder mit dem ersten Zeichen aus OFS zusammengepappt werden. Und die jew. print werden mittels ORS zusammengepappt).
Dafür muß man nicht viel mehr, als einmal die manpage durcharbeiten (kein Vorwurf!).
Diese Zeit hatte ich mir genau nicht genommen. Sonst hätte ich noch einmal nachschauen müssen, wie die Parameter für printf, AWK, die präzise Syntax für AWK lautet etc. Die Mittagspause musste auch noch fürs Magenfüllen herhalten. (^-^)
Der Algorithmus ist jeweils der, den du schon bei deiner Lösung verwendet hast. Und die awk-Lösung ist eben einfach ;)
Nur im adleräugigen Rückblick! Bis man dies erst erstellt hat, ist der Weg nicht so einfach. Einfach ist es erst, wenn man die Syntax sich erarbeitet hat und einige kleine Kniffe kennt.
Im Standard http://www.opengroup.org/onlinepubs/007908799/xcu/awk.html sind alle drei Varianten drin und mit GNU awk -W traditional etc. bekomme ich keine Warnungen. Es sollte also auch 'cnt++' portabel sein.
Da ich nicht viele Oldtimer unter meinen Systemen habe, sollte es auch mit cnt++ gehen. Den Linke jedenfalls habe ich mir notiert, das geht etwas schneller als sich die Optionen über "man awk" zusammenzusuchen.
Hä? Das sind doch praktisch die Manpages, nur eben in der Version, die dem Standard entspricht bzw. diesen definiert ;)
Wenn ich auf der Shell arbeite (nicht Linux als Desktop-System!), dann ist die man page recht mühselig. Da ist es wirklich einfacher, die HTML-Seite nebenher aufzumachen.
PS: melde dich ruhig auch mal per PM ;)
Mache ich, wenn ich wieder auf der statischen Leitung bin. (^-^)
-- Sandy
Antworten bitte nur in die Mailingliste! PMs bitte an: news-reply2 (@) japantest (.) homelinux (.) com -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Rolf-Hubert Pobloth schrieb:
Hallo Liste,
habe ein Frage an die MySQL Spezialisten, da ich mich damit nicht so sehr auskenne benötige ich bei folgendem Problem Eure Hilfe.
[...]
wenn alle zum Kunden 1 gehörigen Zeilen auch im Feld7 den Wert wie hier im Beispiel den Wert 0001 --- 00002 000003 usw haben ist es auch ok. Leider ist eine Bearbeitung mit OpenOffice nicht möglich, da hier die Zeilenbegrenzung auf 65000 zuschlägt.
Ich verstehe Dein Problem nicht so richtig. Aber vielleicht nimmst Du mal den DbVisualizer ( http://www.minq.se/products/dbvis/ ), mit den solltest Du das Problem der Zeilenbegrenzung nicht haben, ist dort einstellbar. Das Programm setzt auf Java auf. HTH Andreas -- Andreas Ernst Publishing & Software Postfach 5, 65612 Beselich Schupbacher Str. 32, 65614 Beselich, Germany Tel: +49-6484-91002 Fax: +49-6484-91003 ae@ae-online.de www.ae-online.de www.tachyon-online.de -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org
Hallo, On Tuesday 30 January 2007 16:52:35 Rolf-Hubert Pobloth wrote:
Leider ist eine Bearbeitung mit OpenOffice nicht möglich, da hier die Zeilenbegrenzung auf 65000 zuschlägt.
Versuche es z.B. mal mit phpMyAdmin oder sonst einem Tool das du auf deiner SUSE findest. Bei mysql selbst ist z.B. ein mysql-query-browser Paket dabei, welches ich aber noch nicht getestet habe. Muss diese Konvertierung mehrmals vorgenommen werden? Wenn ja, wuerde ich ein kleines Pythonscript vorschlagen, oder wenn du fit in C/C++ bist, ist es auch keine Problem damit Queries abzusetzen. Roman -- Roman Fietze Telemotive AG Büro Mühlhausen
participants (6)
-
Andreas Ernst
-
Daniel Bauer
-
David Haller
-
Rolf-Hubert Pobloth
-
Roman Fietze
-
Sandy Drobic