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