wie Regex für sed escapen?

K

Kryptaesthesie

Jungspund
Mahlzeit :)

Ich habe eine Datei, vom Aufbau her etwa so:
Code:
Zeile 1
Zeile 2
Zeile 3
<modi value="ENTW"/>
Zeile 5
Zeile 6
Ziel soll es sein, die Zeile <modi zu ersetzen.
Den Regex habe ich und laut The Regex Coach funktioniert der auch, wie gewünscht. :)

Jetzt möchte ich das aber gerne in einem Script machen.
Also habe ich mir sed aus der Werkzeugkiste geholt. Leider komme ich mit dem Escapen nicht klar.
So sieht mein Script aus:
Code:
echo "vorher:"
echo
cat /home/ich/test_verzeichnis/datei_mit_inhalt.txt
echo
echo
echo
echo "nachher:"
echo
sed -e 's/(<(?i)(modi))\s+value=\"\w*\"\/?>(<\/(?i)(modi)>)?/NEUER_WERT/g' /home/ich/test_verzeichnis/datei_mit_inhalt.txt
echo

# normaler Ausdruck:   (<(?i)(modi))\s+value="\w*"/?>(</(?i)(modi)>)?
# Ausdruck escaped:    (<(?i)(modi))\s+value="\w*"\/?>(<\/(?i)(modi)>)?

Es kommt kein Fehler, aber ersetzt wird auch nichts. :(
Wie, was, wo muss ich da noch escapen?

Ach ja, dass das nach dem Script derzeit noch nicht in der Datei ersetzt wird, sondern auf stdout schreibt, ist mir bekannt. Aber ich wollte auch erst mal nur den sed-Befehl zum Laufen kriegen! :)

Danke für eure Hilfe!
Gruß
Gerrit
 
Hi,

du machst dir das Leben aber schwer.

Ich wuerde ein anderes Trennzeichen fuer sed benutzen, z.B. $ oder |, um das escapen der slashs zu vermeiden (e.g. sed 's$foo$bar$g').

Das eigentliche Problem duerften aber die ganzen Klammern sein, ich sehe keinen Grund fuer die vielen Klammern. Wenn das Gruppierungen sein sollen muessen die Klammern auch alle noch escaped werden, aber ich wuerde sie einfach komplett weglassen.

Dann enthaelt der Ausdruck noch eine Menge Krams der fuer dein Beispiel ueberhaupt nicht gebraucht wird (?i und so Spielchen). Ich wuerde immer mit dem simpelsten Ausdruck anfangen der funktioniert, und dann erst nach und nach die Sonderfaelle hinzufuegen.

mfg,
bytepool
 
Okay, ich habe das Script und auch den Regex noch mal angepasst:
Code:
echo "vorher:"
echo
cat /home/xyz/test_verzeichnis/datei_mit_inhalt.txt
echo
echo
echo
echo "nachher:"
echo
sed -e 's|<(?i)modi\s+value="\w*"\/?>(<\/(?i)modi>)?|NEUER_WERT|g' /home/xyz/test_verzeichnis/datei_mit_inhalt.txt
echo

# normaler Ausdruck:   <(?i)modi\s+value="\w*"/?>(</(?i)modi>)?
# Ausdruck escaped:    <(?i)modi\s+value="\w*"\/?>(<\/(?i)modi>)?

Leider ändert das an dem Ergebnis nichts. Auch nicht, wenn ich die Klammern escape.

Im Anhang ist ein Screenshot, der zeigt, warum der Regex mehr macht, als für das obrige Bsp. nötig.
Aber sicher lässt der sich noch optimieren!


Gruß
Gerrit
 

Anhänge

  • regexscrenshot.jpg
    regexscrenshot.jpg
    134,7 KB · Aufrufe: 3
Hi,

Im Anhang ist ein Screenshot, der zeigt, warum der Regex mehr macht, als für das obrige Bsp. nötig.
kann es sein, dass die komische (?i) Konstruktion fuer "case-insensitive" steht? Also dass er Gross- und Kleinschreibung ignorieren soll? Das wuerde ungefaehr zu dem Screenshot passen. Das wird in sed so aber nicht funktionieren, das ist keine Standard regex Syntax.

Wenn du sowohl auf Gross- als auch auf Kleinschreibung matchen willst, macht man das normalerweise eher so:
Code:
[Mm][Oo][Dd][Ii]

mfg,
bytepool
 
Unter der Annahme, dass zwischen <modi ...></modi> nie etwas steht:
Code:
sed -e 's#<modi\s+value="\(\w*\)"\s*(/>|></modi>)#\1#ig' /home/xyz/test_verzeichnis/datei_mit_inhalt.txt

Ungetestet...

btw. zwischen unterschiedlichen sed-Versionen bestehen teilweise Unterschiede in Syntax oder anderem...
 
so, nun klappt's! :-)

Guten Morgen :)

Ich danke euch für eure Hilfe! :)
Ich habe es nun hinbekommen und es sieht nun so aus:
Code:
echo "vorher:"
echo
cat /home/xyz/test_verzeichnis/datei_mit_inhalt.txt
echo
echo
echo
echo "nachher:"
echo
sed -e 's#<[Mm][Oo][Dd][Ii]\s\+value="\w*"\s\?/\?>\(</[Mm][Oo][Dd][Ii]>\)\?#ABC#ig' /home/xyz/test_verzeichnis/datei_mit_inhalt.txt
echo



### ermittelt nur die kurze Schreibweise:   <modi value="LIVE" />
# normaler Ausdruck:   <[Mm][Oo][Dd][Ii]\s+value="\w*"\s?/>
# Ausdruck escaped:    <[Mm][Oo][Dd][Ii]\s\+value="\w*"\s\?/>


### ermittelt die lange Schreibweise:   <MODI value="LIVE"></MODI>
# normaler Ausdruck:   <[Mm][Oo][Dd][Ii]\s+value="\w*"\s?/?>(</[Mm][Oo][Dd][Ii]>)?
# Ausdruck escaped:    <[Mm][Oo][Dd][Ii]\s\+value="\w*"\s\?/\?>\(</[Mm][Oo][Dd][Ii]>\)\?

Gruß
Gerrit
 
Hi,

eine kosmetische Sache noch. Statt die ganzen echo's einzeln zu schreiben, kannst du auch echo -e mit \n fuer die Zeilenvorschuebe benutzen, also z.B.:
Code:
echo -e "\n\n\nnachher\n"
Ist wie gesagt rein kosmetisch, aber dann blaeht sich der Code nicht so auf.

mfg,
bytepool
 
Hi,

eine kosmetische Sache noch. Statt die ganzen echo's einzeln zu schreiben, kannst du auch echo -e mit \n fuer die Zeilenvorschuebe benutzen, also z.B.:
Code:
echo -e "\n\n\nnachher\n"
Danke für den Hinweis!
Im richtigen / endgültigen Script ist das schon mit \n umgesetzt. Ist wirklich weniger aufgebläht. :)

Gruß
Gerrit
 

Ähnliche Themen

sed - Bitte um Unterstützung

SED: eine Zeile mit einem Grep-Output ersetzen

Text mit mehreren Zeilen und Sonderzeichen ersetzten

Last mit etc/passwd anzeigen lassen

Array im Dateinamen wird nicht erkannt

Zurück
Oben