regex; text zwischen zwei Zeichen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
mullers

regex; text zwischen zwei Zeichen

Beitrag von mullers » 09.10.2011 09:06:10

Mich würde doch mal interessieren, wie man mittels einer regex Text
*zwischen* zwei Zeichen bearbeiten kann, aber die beiden begrenzenden
Zeichen so lässt, wie sie sind.
`look-ahead', bzw. `look-behind' scheinen da ja die Stichwörter zu sein,
deshalb sähe mein Versuch so aus:
die Datei test.txt:

Code: Alles auswählen

das ist eine [test] klammer
mit sed:

Code: Alles auswählen

sed -r 's/(?<=])(.*?)(?=])/ersatz/' test.txt
mit awk habe ich auch probiert, weil ich unsicher bin, ob extended regex
immer mit sed funktionieren:

Code: Alles auswählen

awk '{gsub(/(?<=[)(.*?)(?=])/, "ersatz"); print}' test.txt 
sed macht nichts, und bleibt stumm, awk gibt immerhin diese Fehlermel-
dung aus:

Code: Alles auswählen

awk: line 1: regular expression compile failed (missing operand)
Gruesse
henry

wilfried
Beiträge: 153
Registriert: 04.12.2009 12:32:16

Re: regex; text zwischen zwei Zeichen

Beitrag von wilfried » 09.10.2011 10:08:11

sed -e 's/\[.*\]/\[ersatz\]/g' test.txt
Debian testing (wheezy)
Kernel Linux 3.2.0-3-686-pae
Mainboard: Fujitsu D3041-A1
CPU: Intel Pentium Dual-Core E5800 @ 3.20GHz, 4 GB RAM
Grafik: ATI RV710 [Radeon HD 4350]
eth0: RTL8111/8168B PCI Express Gigabit Ethernet

mullers

Re: regex; text zwischen zwei Zeichen

Beitrag von mullers » 09.10.2011 11:11:53

wilfried hat geschrieben:sed -e 's/\[.*\]/\[ersatz\]/g' test.txt
Nun ja, das löscht halt die Klammern, - und setzt sie nachher wieder
ein. Das Problem ist aber, dass die Klammern zuallerst überhaupt nicht
entfernt werden sollen.

wilfried
Beiträge: 153
Registriert: 04.12.2009 12:32:16

Re: regex; text zwischen zwei Zeichen

Beitrag von wilfried » 09.10.2011 11:41:40

myyers hat geschrieben: Nun ja, das löscht halt die Klammern, - und setzt sie nachher wieder
ein. Das Problem ist aber, dass die Klammern zuallerst überhaupt nicht
entfernt werden sollen.
erzielt aber den gewünschten Effekt,
ansonsten, hab ich auch keine Ahnung, wie man die eckigen Klammern escapen kann...
Debian testing (wheezy)
Kernel Linux 3.2.0-3-686-pae
Mainboard: Fujitsu D3041-A1
CPU: Intel Pentium Dual-Core E5800 @ 3.20GHz, 4 GB RAM
Grafik: ATI RV710 [Radeon HD 4350]
eth0: RTL8111/8168B PCI Express Gigabit Ethernet

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: regex; text zwischen zwei Zeichen

Beitrag von detix » 09.10.2011 12:07:53

Bin mir ja sicher das es bessere Lösungen gibt...

Code: Alles auswählen

echo 'das ist eine [test] klammer' | sed 's/\(.*\[\).*\(\].*\)/\1neue\2/'
das ist eine [neue] klammer
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

mullers

Re: regex; text zwischen zwei Zeichen

Beitrag von mullers » 10.10.2011 09:53:37

Danke!
Soweit ich das verstanden habe, funktioniert `look-ahead/behind' nicht mit
sed search/replace. Wie auch immer so gehts ja auch.

Gruesse
henry

Benutzeravatar
Livingston
Beiträge: 1816
Registriert: 04.02.2007 22:52:25
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: 127.0.0.1

Re: regex; text zwischen zwei Zeichen

Beitrag von Livingston » 10.10.2011 16:03:57

Vielleicht liegt ein kleines Missverständnis vor. sed verändert die ursprüngliche Datei (oder allgemeiner: den Eingabestream) nicht. Den Output musst Du ohnehin mit Hilfe von ">" oder "|" einfangen und in eine neue Datei (oder wohin auch immer) umlenken. Insofern wird eigentlich nix ersetzt, sondern durch sed unter Beachtung der regExe was Neues gebaut.

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: regex; text zwischen zwei Zeichen

Beitrag von Meillo » 15.10.2011 10:21:24

Ich kommentiere mal zusammenfassend.
myyers hat geschrieben:Danke!
Soweit ich das verstanden habe, funktioniert `look-ahead/behind' nicht mit
sed search/replace.
Das Konzept von look-* ist den klassischen Unix-Tools fremd. Das kennt man von Perl.
myyers hat geschrieben: Nun ja, das löscht halt die Klammern, - und setzt sie nachher wieder
ein. Das Problem ist aber, dass die Klammern zuallerst überhaupt nicht
entfernt werden sollen.
Das ist so im portablen sed nicht moeglich. Entweder du weisst was ersetzt wird, dann kannst du es direkt in den Ersatztext schreiben (wie hier) oder du musst Klammern und Rueckwaertsreferenzen verwenden.
wilfried hat geschrieben:sed -e 's/\[.*\]/\[ersatz\]/g' test.txt
In solchen Faellen ist meist /\[[^]]*\]/ was man will.
detix hat geschrieben:Bin mir ja sicher das es bessere Lösungen gibt...

Code: Alles auswählen

echo 'das ist eine [test] klammer' | sed 's/\(.*\[\).*\(\].*\)/\1neue\2/'
das ist eine [neue] klammer
Grundsaetzlich ist es unnoetig den Prefix und Postfix der Zeile manuell zu kopieren. Ersetzt wird ja doch nur worauf das Pattern matcht, der Rest wird ohnehin durchkopiert. Deshalb:

Code: Alles auswählen

sed 's/\(\[\).*\(\]\)/\1neue\2/g'
Diese Form ist fuer variable Begrenzer geeignet. Da hier die eckigen Klammern aber fix sind ist die Variante von wilfried einfacher.
Livingston hat geschrieben:Vielleicht liegt ein kleines Missverständnis vor. sed verändert die ursprüngliche Datei (oder allgemeiner: den Eingabestream) nicht. Den Output musst Du ohnehin mit Hilfe von ">" oder "|" einfangen und in eine neue Datei (oder wohin auch immer) umlenken. Insofern wird eigentlich nix ersetzt, sondern durch sed unter Beachtung der regExe was Neues gebaut.
Nein, das ist hier nicht relevant, da myyers sich dessen bewusst ist. Trotzdem danke fuer den Hinweis.
Use ed once in a while!

Antworten