awk oder sed, textmanipulation

M

morebray

Grünschnabel
Hallo,
ich versuche in einer Datei, in jeder Zeile, in einer bestimmten Spalte (6 und 10), von einer Zahl (Währung US) die Kommas weg zu bekommen, oder durch

einen Punkt zu ersetzen.
Da in der Zeile die Spalten duch Kommas getrennt werden hab ich ein Problem.

Habe es mit folgenden sed probiert:
sed 's/\([0-9]*\),\([0-9][0-9]\)/\1.\2/g' Dateiname.csv

Der Inhalt sieht so aus (vorher):
PremCurrMst,79890126,8-May-08,S,USD,"-1,250,000.00",1.012412,B,CAD,"1,265,515.00",30-May-08,8129NN00149,CONFIRMED

Was dann rauskommt, sieht dann so aus (nachher):
PremCurrMst.79890126,8-May-08,S,USD,"-1.250.000.00",1.012412,B,CAD,"1.265.515.00".30-May-08.8129NN00149,CONFIRMED

Leider wird hierbei ab der 1. Spalte das Komma auch durch den Punkt ersetzt!?

Da ja die Zahl (Währung US) in Hochkommas stehen könnte man das ja als Anhaltspunkt nehmen, aber das bekomme ich leider nicht mit dem "awk" oder "sed"

hin.

Super wenn mir jemand helfen könnte! ?(


Grüße
Volker
 
Hier mal ein perl oneliner:
Code:
perl -anF\" -e '$F[1]=~tr/,/./;$F[3]=~tr/,/./;print join(q{"}, @F)' Dateiname.csv
Der Input wird in durch Doublequotes separierte Felder getrennt und dann werden in Feld 2 und Feld 4 (die Währungsspalten) jeweils alle Kommata durch Punkte ersetzt. (Wenn das so auch in awk geht, möge man es mir aufzeigen. Aber ich kannte so aus dem Stehgreif kein awk-Äquivalent zu tr///, seds y/// oder gar s///)

Das funktioniert selbstredend nur, wenn da immer nur exakt 2 double-quotet Strings im Input pro Zeile sind, und diese Strings immer diese US-Dollar Spalten darstellen.

Wenn du awk (und sed ein wenig) kennst, so sähe das in awk aus:
Code:
awk -F'"' '{$2 =~ tr/,/./; $4 =~ tr/,/./; print $0}' Dateiname.csv
Nur das awk tr wohl nicht kennt. (In sed wäre das y///)
 
Hallo
Wenn du es mit sed machen willst:
Code:
$ cat test
PremCurrMst,79890126,8-May-08,S,USD,"-1,250,000.00",1.012412,B,CAD,"1,265,515.00",30-May-08,8129NN00149,CONFIRMED

$ sed -e 's/\([[:digit:]]\{1\}\)\,\([[:digit:]]\{2\}\)/\1.\2/g'  test
PremCurrMst,79890126,8-May-08,S,USD,"-1.250.000.00",1.012412,B,CAD,"1.265.515.00",30-May-08.8129NN00149,CONFIRMED

Gruß Wolfgang
 
wegen: awk oder sed, textmanipulation

Hallo, vielen Dank für den Input!

Bin leider nicht der "Guru" wie ihr in diesen Sachen.
Aber das funktioniert super, bin begeistert!!

Der Perl oneliner funktioniert super ! (Danke Gott_in_schwarz)

Der sed oneliner ist auch super, (Danke Wolfgang)
aber leider wurde nach dem letzten Datum (11. Spalte) das Komma auch in einen Punkt umgesetzt.
Ich hab schon mal rumprobiert, leider komme ich da nicht weiter.

viele Grüße
Volker
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

Hi, ich nochmal,

habe eben meinen Fehler in der Beschreibung gemerkt!

Es sollen natürlich nur die Kommas entfernt werden in der 6. und 10. Spalte.
Beispiel: "1,000,000.00" soll als 1000000.00 dargestellt werden, auch die hochkommas sollen da weg.
Ist doch etwas komlizierter als ich gedacht hatte.

- Da müsste ich wohl Zwei "perl oder sed" oneliner hintereinander laufen lassen, um erst die Kommas weg zu bekommen und dann noch die Hochkommas-?(

sorry mein Fehler.

Grüße
Volker
 
Zuletzt bearbeitet:
So?
Code:
perl -anF\" -e 'tr/,//d for @F[1, 3];print @F' Dateiname.csv
Input:
Code:
PremCurrMst,79890126,8-May-08,S,USD,"-1,250,000.00",1.012412,B,CAD,"1,265,515.00",30-May-08,8129NN00149,CONFIRMED
Output:
Code:
PremCurrMst,79890126,8-May-08,S,USD,-1250000.00,1.012412,B,CAD,1265515.00,30-May-08,8129NN00149,CONFIRMED
Änderungen: tr ändert Kommata jetzt nicht in Punkte um, sondern löscht sie. (Nur in den betreffenden Spalten natürlich..) Und das erstelle "Feld-Array" wird diesmal nicht zur Ausgabe mit doublequotes "gejoint" (zusammengefügt), sondern einfach mit Leerstrings. (print @arr)
 
1000 Dank, Gott_in_schwarz,
das funktioniert super !!
Das hätte ich nicht in Perl hinbekommen.

viele Grüße
Volker
 
Hallo, bin neu hier im Board und möchte eine ganz ähnliche Manipulation einer vorhandenen Textdatei vornehmen. Auch bei mir geht es um Spalten im gewissen Sinne. Meine Wunschvorstellung sieht so aus:

aus einer Textdatei alle Zeilen löschen deren 6. bzw. 9. Spalte (noch besser die 7. und 8. ebenso) identisch sind. Es handelt sich um Zahlenwerte d.h. die Division der beiden (vier) Spalten miteinander muss im Ergebnis also 1 sein.

Geforscht habe ich bislang nach Sed, AWK, UNIQ.. bislang ohne Erfolg. Bin allerdings ne ziemliche Programmierniete, muss man dazu sagen..

ERBSEN,BOHNEN,LINSEN,20080526,SUPPE,555,777,444,666,0,0
ERBSEN,BOHNEN,LINSEN,20080527,SUPPE,555,555,555,555,0,0
ERBSEN,BOHNEN,LINSEN,20080528,SUPPE,888,999,333,666,0,0


konkret müsste also im gezeigten Bsp. die zweite Zeile mit dem Datum von gestern gelöscht werden. Bin für jede Hilfe oder jeden brauchbaren Hinweis dankbar!


Achso, als Nachtrag, falls das von Interesse ist, mein Betriebssystem hier ist Windows XP d.h. ich arbeite mit den CoreUtils in der Version 5.3.0

http://gnuwin32.sourceforge.net/packages/coreutils.htm
 
Zuletzt bearbeitet:
Schade dass sich bislang keine Lösung hat finden lassen. Evtl. ist das Problem doch nicht so trivial, wie ich dachte? Oder gar zu trivial? ?(

An die Moderatoren: wenn ich lieber einen eigenen Thread eröffnen sollte, um meine Chance auf Beantwortung zu steigern, lasst es mich wissen..

Gruß

EDIT: so oder ähnlich hatte ich es mir vorgestellt, aber die Syntax stimmt wohl vorne bis hinten nicht..

gawk "!{ if ($6/$9=1)}" in >out
 
Zuletzt bearbeitet:
Ich fand dein erstes Post ein wenig zu diffus formuliert um darauf zu antworten. Und ja: das Problem ist trivial. Man kann übrigens einfach Zwei Werte direkt auf Gleichheit überprüfen statt zu dividieren und das Ergebnis dann mit 1 zu vergleichen...

Aber das hier:
aus einer Textdatei alle Zeilen löschen deren 6. bzw. 9. Spalte (noch besser die 7. und 8. ebenso) identisch sind. Es handelt sich um Zahlenwerte d.h. die Division der beiden (vier) Spalten miteinander muss im Ergebnis also 1 sein.
Also erstmal diese verschwurbelte Idee mit der Division und dann: welche Spalten denn jetzt genau? Hier mal ein paar (IHMO) mögliche Permutationen für eine If-Abfrage:
Code:
$6 == $9
#oder:
($6 == $9) && ($7 == $8)
#oder:
($6 == $9) && ($6 == $8) && $($6 == $7)
#oder:
($6 == $9) || ($7 == $8)
Und da hatte ich halt keinen Bock zu raten. Aber da du ja jetzt quasi eine if-Abfrage vorgegeben hast, hier mal'n Fetzen perl:
Code:
echo 'ERBSEN,BOHNEN,LINSEN,20080526,SUPPE,555,777,444,666,0,0
ERBSEN,BOHNEN,LINSEN,20080527,SUPPE,555,555,555,555,0,0
ERBSEN,BOHNEN,LINSEN,20080528,SUPPE,888,999,333,666,0,0'|
perl -anF, -e 'print if $F[5] != $F[8]'
Und [g]awk-Syntax lässt sich btw auch nachlesen/-schlagen:
*klick mich hart*
 
Ein Grund, warum z.B. ich persönlich nicht darauf eingehe:
Achso, als Nachtrag, falls das von Interesse ist, mein Betriebssystem hier ist Windows XP d.h. ich arbeite mit den CoreUtils in der Version 5.3.0

Diese Kombination hat nichts mit einer Unix Shell zu tun, ist hier sozusagen reichlich OT. Ich kenne weder WinXP noch diese utils. Ich weiß aber aus Erfahrung, daß Lösungsansätze für eine echte Unix/Linux Shell nicht so einfach auf Windows-Notlösungen portierbar sind.

Ein weiterer Grund ist deine sehr "diffus" beschriebene Aufgabe.

Dir wird also nur das Studium der Syntax deiner verwendeten Werkzeuge bleiben.

Wolfgang
 
Hallo, da ich in der Zwischenzeit im Urlaub gewesen bin und jetzt zufällig über eure Antworten gestolptert bin - danke dafür - wollte ich allen interessierten meine Lösung nicht vorenthalten, wie ich sie umgesetzt habe:

gawk -F, "$6!=$9 && $7!=$8 { print }"

Übrigens ich nutze aus guten Gründen SOWOHL Linux als auch Windows, da unter Linux einfach noch nicht alle meine Bedürfnisse abgedeckt werden konnten. Ich glaube nicht, daß dies eine Schande ist..

Gruß
 

Ähnliche Themen

sed: alle Zeilen entfernen die keine Zahl enthalten

sed macht mich wahnsinnig :-(

Textdatei manipulieren mittels sed

sed im script per crontab

HP PSC 2175 - CUPS druckt nicht

Zurück
Oben