sed - alle strings zwischen 2 andere strings ersetzen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
stdio
Beiträge: 6
Registriert: 06.09.2005 12:53:14

sed - alle strings zwischen 2 andere strings ersetzen

Beitrag von stdio » 06.09.2005 12:59:21

hallo

angenommen ich hab die datei data.txt:

bar start bar end bar

und will alle "bar"'s zwischen start und end mit foo ersetzen, wie wuerde das sed script dazu aussehen?

ich hab's mit
sed -e '/start/,/end/{s/bar/foo/g;}'
versucht, allerdings wurden dann jeweils saemtliche bars mit foo ersetzt
weiss vielleicht einer wie ich's richtig anstelle? =)
danke im voraus,

gruesse
stdio

Benutzeravatar
godsmacker
Beiträge: 902
Registriert: 16.03.2003 21:50:26
Lizenz eigener Beiträge: Artistic Lizenz
Wohnort: Chemnitz
Kontaktdaten:

Beitrag von godsmacker » 06.09.2005 13:00:56

Ich würde

Code: Alles auswählen

 perl -pi -e 's/foo/bar/ if (/start/ .. /end/)' file
verwenden.

-Flo

Benutzeravatar
SubOptimal
Beiträge: 1709
Registriert: 10.01.2005 23:25:46
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: bei Frankfurt

Beitrag von SubOptimal » 06.09.2005 13:07:21

Hi stdio,

z.B. so:

Code: Alles auswählen

sed -n 's/\(^.*start\).*\(end.*\)/\1 foo \2/p' data.txt
SubOptimal

stdio
Beiträge: 6
Registriert: 06.09.2005 12:53:14

Beitrag von stdio » 06.09.2005 13:10:58

godsmacker hat geschrieben:Ich würde

Code: Alles auswählen

 perl -pi -e 's/foo/bar/ if (/start/ .. /end/)' file
verwenden.

-Flo
hi

danke fuer die rasche antwort!
leider hatte ich nie viel mit perl zu tun, deshalb habe ich einfach mal alles copied & pasted
ergebnis:
es wurde jeweils der erste eintrag von bar in einer zeile ersetzt

Benutzeravatar
godsmacker
Beiträge: 902
Registriert: 16.03.2003 21:50:26
Lizenz eigener Beiträge: Artistic Lizenz
Wohnort: Chemnitz
Kontaktdaten:

Beitrag von godsmacker » 06.09.2005 13:14:15

Hoppla.

Code: Alles auswählen

perl -pi -e 's/foo/bar/g if (/start/ .. /end/)'
-Flo

Benutzeravatar
Savar
Beiträge: 7174
Registriert: 30.07.2004 09:28:58
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Beitrag von Savar » 06.09.2005 13:16:10

Code: Alles auswählen

sed 's/start bar/start foo/' data.txt
MODVOICE/MYVOICE
Debianforum Verhaltensregeln
Log Dateien? -> NoPaste

stdio
Beiträge: 6
Registriert: 06.09.2005 12:53:14

Beitrag von stdio » 06.09.2005 13:20:43

SubOptimal hat geschrieben:Hi stdio,

z.B. so:

Code: Alles auswählen

sed -n 's/\(^.*start\).*\(end.*\)/\1 foo \2/p' data.txt
SubOptimal
funktioniert gut, das problem hierbei ist allerdings, dass auch alle anderen daten zwischen start und end verloren gehen
godsmacker hat geschrieben:Hoppla.

Code: Alles auswählen

perl -pi -e 's/foo/bar/g if (/start/ .. /end/)'
-Flo
funktioniert perfekt, danke! =)

stdio
Beiträge: 6
Registriert: 06.09.2005 12:53:14

Beitrag von stdio » 06.09.2005 14:11:14

godsmacker hat geschrieben:Hoppla.

Code: Alles auswählen

perl -pi -e 's/foo/bar/g if (/start/ .. /end/)'
-Flo
hm, funktioniert doch nicht
auch hier werden wieder jeweils alle eintraege ersetzt, nicht nur die zwischen start und end
Savar hat geschrieben:

Code: Alles auswählen

sed 's/start bar/start foo/' data.txt
das 2. start muss wohl end sein? ging auch nicht :/

Benutzeravatar
godsmacker
Beiträge: 902
Registriert: 16.03.2003 21:50:26
Lizenz eigener Beiträge: Artistic Lizenz
Wohnort: Chemnitz
Kontaktdaten:

Beitrag von godsmacker » 06.09.2005 14:23:45

stdio hat geschrieben:
godsmacker hat geschrieben:Hoppla.

Code: Alles auswählen

perl -pi -e 's/foo/bar/g if (/start/ .. /end/)'
-Flo
hm, funktioniert doch nicht
auch hier werden wieder jeweils alle eintraege ersetzt, nicht nur die zwischen start und end
test.data:

Code: Alles auswählen

foo bar
start
foo bar
end
foo bar

Code: Alles auswählen

perl -pi -e 's/foo/bar/g if (/start/ .. /end/)' < test.data
foo bar
start
bar bar
end
foo bar

Benutzeravatar
Savar
Beiträge: 7174
Registriert: 30.07.2004 09:28:58
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Beitrag von Savar » 06.09.2005 14:27:50

@godsmacker: ich dachte "bar start bar end bar" wäre in einer Zeile??!

@stdio: nein es sollte beide male ein "start" dastehen.. kannst du nicht mal nen Ausschnitt aus der Datei posten?..
MODVOICE/MYVOICE
Debianforum Verhaltensregeln
Log Dateien? -> NoPaste

stdio
Beiträge: 6
Registriert: 06.09.2005 12:53:14

Beitrag von stdio » 06.09.2005 14:43:46

die eintraege sind auf einer zeile, deshalb funktioniert godsmackers loesung leider nicht

beim file handelt es sich um ein xml file dessen aufbau etwa so aussieht:

<document>
<entry><id>1</id><foo>123456789</foo><dontchange>123456789</dontchange></entry>
<entry><id>1</id><foo>987654321</foo><dontchange>987654321</dontchange></entry>
</document>

ich versuche also den inhalt von foo zu veraendern ohne den inhalt von dontchange oder id auch zu veraendern

ich dachte ich haette es so loesen konnen:

Code: Alles auswählen

sed -e '/foo/,/\/foo/{y/0123456789/9876543210/;}'
war aber nicht so :/

egal ob y/*/*/ oder s/*/*/g, er aenderte jeweils die treffer der ganzen zeile

Benutzeravatar
godsmacker
Beiträge: 902
Registriert: 16.03.2003 21:50:26
Lizenz eigener Beiträge: Artistic Lizenz
Wohnort: Chemnitz
Kontaktdaten:

Beitrag von godsmacker » 06.09.2005 14:46:36

Nimm doch XML und XPath dazu. Ist eigentlich wie gemacht dafür.

-Flo

Benutzeravatar
Savar
Beiträge: 7174
Registriert: 30.07.2004 09:28:58
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Beitrag von Savar » 06.09.2005 14:47:11

ähm.. heißen die dann alle unterschiedlich? also id und foo und dontchange ?? Bitte poste mal eine konkrete Zeile... ansonsten verwirrst du mehr als das uns die Infos was bringen..
MODVOICE/MYVOICE
Debianforum Verhaltensregeln
Log Dateien? -> NoPaste

stdio
Beiträge: 6
Registriert: 06.09.2005 12:53:14

Beitrag von stdio » 06.09.2005 14:57:29

die tags sind jeweils unterschiedlich, kein tag kommt mehrmals in einer zeile vor
der inhalt jedoch kann mehrere male in verschiedenen tags aufkommen

ich wuerde gerne eine loesung als bourne-shell skript haben, da ich diesen
vorgang automatisieren will

edit: das was ich oben gepostet habe, ist sozusagen aus dem original xml file kopiert, lediglich die tag namen wurden veraendert

Benutzeravatar
Savar
Beiträge: 7174
Registriert: 30.07.2004 09:28:58
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Beitrag von Savar » 06.09.2005 15:16:10

na das sollte doch so gehen wie schonmal beschrieben?!

Code: Alles auswählen

sed -e 's/<foo>123456789</foo>/<foo></foo>/' DATEID.xml
MODVOICE/MYVOICE
Debianforum Verhaltensregeln
Log Dateien? -> NoPaste

Antworten