Forum: PC-Programmierung sed unter Windows mit Problemen


von Schulze (Gast)


Lesenswert?

Hallo,

ich habe gerade ein ganz triviales Problem mit dem Programm sed unter 
Windows.

http://gnuwin32.sourceforge.net/packages/sed.htm

Ich möchte eine sehr umfangreiche CSV-Datei umformatieren und das 
Ergebnis wieder in eine Datei ausschreiben lassen. Unter Linux klappt 
das hervorragen, unter Windows nicht.

In der Eingabeaufforderung (Win7, 64Bit) wird der Aufruf

sed -e '...' test.csv > test_neu.csv, '...' sei irgend eine Anweisung, 
zwar ausgeführt, der Operator > jedoch nicht erkannt. Somit landet das 
Ergebnis Zeile um Zeile wieder in der Eingabeaufforderung.

Ich habe im Netz oder in den Dokus zu Sed für Windows nicht finden 
können, wie ich das Problem mit dem > löse.


Ich hoffe auf einen hilfreichen Hinweis von euch.

Mit Gruß

Schulze

von Peter II (Gast)


Lesenswert?

eventuell schreibt sed ja auf stderr
1
sed -e '...' test.csv > test_neu.csv 2>&1

von Schulze (Gast)


Lesenswert?

Hallo Peter,

leider bringt dein Hinweis keine Besserung. Die Ausgabe von sed läuft 
weiter nur auf die Anzeige. Fehlermeldung: "sed: kann > nicht lesen: 
Invalid argument"

Der Operator wird auch nicht über \> erkannt

Hast du evtl. einen weiteren Tipp?

Gruß

Schulze

von Peter II (Gast)


Lesenswert?

funktioniert denn ein andere befehl mit Umleitung?
1
dir > test.txt
2
3
echo -e '...' test.csv > test_neu.csv 
4
5
6
sed -e '...' test.csv > test_neu.csv

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die Windows-"Eingabeaufforderung" kann zwar mit > Ausgaben in Dateien
umleiten, kennt aber keine Apostrophe, um die Vorverarbeitung von
Kommandzeilenargumenten zu unterbinden. Wahrscheinlich enthält bei dir
das Sed-Skript in '...' irgendein Zeichen, das die "Eingabeaufforderung"
durcheinander bringt.

Du kanst versuchen, das Skript stattdessen von einer Datei zu lesen:

1
sed -f scriptfile test.csv > test_neu.csv

Edit: Apostrophe scheint es in Windows doch zu geben, aber sie werden
anders interpretiert als in einer Unix-Shell. Enthält das in Apostrophen
eingeschlossene Skript bspw. ein >-Zeichen, dann passieren seltsame
Dinge.

: Bearbeitet durch Moderator
von Schulze (Gast)


Lesenswert?

Hallo,

das Problem scheint umständlicher.

Ja, der Umleitungsoperator wird z.B. mit dir erkannt und ausgeführt. 
Somit kann das nicht der Grund für sed sein.

Ich habe gerade etwas experimentiert. Mein konkreter Aufruf unter Linux 
lautet und er funktioniert:

sed -e '1,1d' -e 's/\"//g' -e 's/,/./g' test.csv > test_neu.csv

lösche 1. Zeile, tausche alle , gegen . und entferne alle ".

Unter Windows läuft das nicht. Aber es liegt nicht am ">". Offenbar mag 
er das 2. Skript nicht.

Unter Windows:

sed -e "1,1d" -e "s/\"//g" -e "s/,/./g" "test.csv" > "test_neu.csv"

Entferne ich das 2. Skript, so funktionert die Umleitung. Lasse ich es 
drin, erfolgt die korrekte Ausgabe auf dem Bildschirm. Die Anweisung 
"s/\"//g" wird also richtig interpretiert und alle " aus der Tabelle 
entfernt. Es erfolgt nur keine Ausgabe in eine Datei...

Hast du eine Idee?

Gruß

Schulze

von Schulze (Gast)


Lesenswert?

Herzlichen Dank für den Hinweis!

Die Lösung liegt in der Verwendung eines Sed-Scriptes als eigenständige 
Datei. Also sed -f script test.csv > test_neu.csv.


Das wird mir eine menge Arbeit sparen.

Vielen Dank und bis zur nächten Frage :)

Schulze

von Bernd B. (Gast)


Lesenswert?

Für das zweite Script geht auch

-e "s/""""""//g"

Die Windows-Kommandozeile ist schon ein bisschen speziell :-)

von ./. (Gast)


Lesenswert?

Nuex als Laien hier.

Das Escapezeichen von cmd.exe ist: ^

Und statt dem sed 2 Expressions anzudrehen, kann Mann die
auch mit einem ';' separiert, in 1 Ausdruck tun.

von Bernd B. (Gast)


Lesenswert?

Dann zeige doch mal den sed-Ausdruck, mit dem man (unter Benutzung von 
^) Anführungszeichen ersetzen kann.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

./. schrieb:
> Nuex als Laien hier.

Mag ja sein, aber cmd.exe ist (als simplester Abklatsch der Unix-Shell 
von 1970) als Interpreter einfach nur schlecht. Bill Gates & Konsorten 
aus der Garage konnten das damals einfach nicht besser.

Aber unkenntlich machen wollten sie die gewollte Nähe zu Unix schon, 
indem sie alle Sonderzeichen durch andere ersetzten:

Programm-Optionen werden unter UNIX mit '-' eingeleitet. MS: Wir nehmen 
stattdessen '/'.

Also Unix: ls -a
DOS: dir /a

Das Escape-Zeichen ist in C sowohl als auch in der UNIX-Shell der 
Backslash '\'. MS: Da nehmen wir stattdessen '^'.

Dateipfad-Trenner ist unter Unix das '/'. MS: Da nehmen wir halt '\'. 
Und so geht das weiter.

Wenn man diese Änderungen nicht alle im Kopf hat, wird man von Dir als 
Laie bezeichnet. Nun gut, meinetwegen. Dann musst Du die 
MS-Programmierer, die das Programm netstat vom Vorbild UNIX gekupfert 
haben, aber auch als Laien bezeichnen, denn dort kann man auch mit '-' 
Optionen kenntlich machen statt wie sonst nur mit '/'. Upps. Und von 
diesen "Anomalien" von Windows-Dienstprogrammen gibt es dutzende, siehe 
auch tracrt & Co.

Also: Nicht nur Laien hier, sondern auch bei MS selbst. Das relativiert 
und beruhigt. ;-)

: Bearbeitet durch Moderator
von Yalu X. (yalu) (Moderator)


Lesenswert?

Ich zähle mich auch zu den Windows-Laien, würde aber gerne etwas
dazulernen, denn das cmd.exe bzw. der Batch-Interpreter vom Windows ist
für einen, der eine Unix-Shell wie Bash gewohnt ist, schon eine extrem
harte Nuss.

Ich habe mir gerade folgende Knobelaufgabe ausgedacht, für die ich
selber nur Teillösungen gefunden habe:

Gesucht ist ein Batch-Skript für Windows (nennen wir es writeln.bat),
das zwei Kommandzeilenargumente entgegennimmt, wobei das erste ein
Textstring und das zweite ein Dateiname ist. Nach der Ausführung des
Skripts soll in der angegebenen Datei der Textstring, eingeschlossen in
spitzen Klammern (<...>) stehen.

Beispiel:

Aufruf mit

1
writeln hallo datei.txt

Danach soll in datei.txt

1
<hallo>

stehen.

Das habe ich gerade noch hinbekommen. Jetzt möchte ich als Textstring
aber anstelle von "hallo" ein einzelnens Anführungszeichen mit jeweils
einem Leerzeichen davor und danach übergeben, so dass anschließend

1
< " >

in der Datei steht.

Wie muss dazu die Batch-Datei und der Aufruf derselben aussehen?


In Linux muss ich nicht lange überlegen:

Shell-Skript:

1
#!/bin/sh
2
echo "<$1>" > "$2"

Aufruf:

1
writeln ' " ' datei

Aber wie geht das mit einer Windows-Batch-Datei?

Eine vollständige (!) Dokumentation zu cmd.exe und den Batch-Interpreter
(vergleichbar mit dem Bash-Manual) würde die Sache sicher erleichtern.
Leider kann ich so etwas nirgends finden.


Das Ganze ist zwar etwas offtopic, ich bin mir aber sicher, dass die
Lösungs des Problems einen befähigt, auch komplizierteste Sed-Skripte
direkt von der Kommandozeile (ohne den Umweg über einen Datei)
einzugeben.

von Bernd B. (bbrand)


Lesenswert?

Yalu X. schrieb:
> Aber wie geht das mit einer Windows-Batch-Datei?

Nachdem ich jetzt fast eine Stunde lang erfolglos rumprobiert habe, kann 
ich nur sagen: Du bist gemein!  :-)

von ./. (Gast)


Lesenswert?

> Dann zeige doch mal den sed-Ausdruck, mit dem man (unter Benutzung
> von ^) Anführungszeichen ersetzen kann.

Datei d:
"
""
"""

Das ja nun einfach:

sed "p;s/["^""]/#/g" d
"
#
""
##
"""
###

Gleich nochmal mit einem ";" zwei Kommandos uebergeben...

von ./. (Gast)


Lesenswert?

P.S.:

sed "p;s/"^""/#/g" d

geht natuerlich.

Und, noch viel lustiger, man braucht gar nichts zu escapen:

sed "p;s/"""/#/g" d


Nuex als Laien hier.

von ./. (Gast)


Lesenswert?

> Aber wie geht das mit einer Windows-Batch-Datei?

Das ist auch einfach.
Mann darf natuerlich nicht das eingebaute echo benutzen.

SCRIPT.CMD:
C:\BIN\echo.exe ^<%1^> >%2

Aufruf:
SCRIPT " "" " DATEI

DATEI:
< " >

von Bernd B. (bbrand)


Lesenswert?

> sed "p;s/"^""/#/g" d
>
> geht natuerlich.

Huh!?

Geht tatsächlich. Ich bin mir absolut sicher, dass ich diese Kombination 
ohne Erfolg ausprobiert hatte. War allerdings auf einem anderen Rechner 
mit einer möglicherweise anderen Version von sed.

> Und, noch viel lustiger, man braucht gar nichts zu escapen:
>
> sed "p;s/"""/#/g" d

Geht nicht! Jedenfalls nicht, wenn man versucht, die Ausgabe in eine 
Datei umzuleiten, was Teil der Aufgabenstellung war.

von Bernd B. (bbrand)


Lesenswert?

./. schrieb:
> Mann darf natuerlich nicht das eingebaute echo benutzen.

Na toll!
Wenn man schon das Unix echo benutzt kann man sich's dann auch noch 
einfacher machen und sh.exe starten :-)

von ./. (Gast)


Lesenswert?

> Wenn man schon das Unix echo benutzt kann man sich's dann auch noch
> einfacher machen und sh.exe starten :-)

Das war nicht gefragt.

> Geht tatsächlich. Ich bin mir absolut sicher, dass ich diese Kombination
> ohne Erfolg ausprobiert hatte.

Das behaupten alle.

von Yalu X. (yalu) (Moderator)


Lesenswert?

./. schrieb:
> Das ist auch einfach.
> Mann darf natuerlich nicht das eingebaute echo benutzen.
>
> SCRIPT.CMD:
> C:\BIN\echo.exe ^<%1^> >%2

Ich habe hier keinen Windows-PC, bin mir aber ziemlich sicher, dass es
auf dem Windows-7-PC, den ich sonst benutze, kein Verzeichnis C:\BIN,
geschweige denn ein echo.exe gibt. Muss ich das erst installieren oder
womöglich sogar selber schreiben?

Bernd B. schrieb:
> Wenn man schon das Unix echo benutzt

Ach so, daher weht der Wind :)

Bernd B. schrieb:
> kann man sich's dann auch noch einfacher machen und sh.exe starten :-)

./. schrieb:
> Das war nicht gefragt.

Dann ist die Aufgabe mit den Boardmitteln von Windows also nicht lösbar?
Ich hätte eigentlich gedacht, dass es da vielleicht irgendeinen Trick
gibt, den ich nur nicht kenne.

von ./. (Gast)


Lesenswert?

> Ich habe hier keinen Windows-PC, bin mir aber ziemlich sicher, dass es
> auf dem Windows-7-PC, den ich sonst benutze, kein Verzeichnis C:\BIN,
> geschweige denn ein echo.exe gibt. Muss ich das erst installieren oder
> womöglich sogar selber schreiben?

Wer faul ist, installiert einfach git.

Wer es richtig drauf hat, tippt das im a-mode in ein debug.com ein.

Und: Wer sed.exe auf seiner M$-Kiste hat, sollte wissen wo
er ein echo.exe herbekommt.

Stellersichnichsoan.


> Dann ist die Aufgabe mit den Boardmitteln von Windows also nicht lösbar?

Nur in der neuen Kluckubuntuausgabe von WiX.

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.