Parsen und ersetzen eines Wortes

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Generic1
Beiträge: 78
Registriert: 15.11.2012 13:41:28

Parsen und ersetzen eines Wortes

Beitrag von Generic1 » 13.03.2013 15:58:59

Hallo,

eine Frage hätte ich noch bzgl. parsen eines XML- Files.
das XML schaut so aus:

Code: Alles auswählen

<root>
    <mytag type="myType" myID="link://platzhalter" />
</root>
Ich möchte mit einem Script jetzt nach "myID="link://"" suchen und dann den "platzhalter" z.B. durch 10.11.12.13 austauschen.
Wie könnte ich das am einfachsten machen.
Besten Dank!!
lg
Generic1

uname
Beiträge: 12406
Registriert: 03.06.2008 09:33:02

Re: Parsen und ersetzen eines Wortes

Beitrag von uname » 13.03.2013 16:07:16

Ich biete mal "sed" an:

Code: Alles auswählen

sed 's/myID=\"link:\/\/platzhalter/myID=\"link\/\/10\.11\.12\.13/g' alt.xml > neu.xml 
sed -i 's/myID=\"link:\/\/platzhalter/myID=\"link\/\/10\.11\.12\.13/g' alt.txt
In der zweiten Version wird die Originaldatei sofort geändert. Bitte mit Testdaten verifizieren. Wichtig ist Anführungszeichen, Punkte und Slashes mit einem Backslahs (\) zu escapen.

Generic1
Beiträge: 78
Registriert: 15.11.2012 13:41:28

Re: Parsen und ersetzen eines Wortes

Beitrag von Generic1 » 13.03.2013 16:32:05

Besten Dank, ich dachte das ist kniffliger :-) Ich steht mir sed nämlich a bissl auf Kriegsfuß.
Eine Frage hätte ich noch, wenn statt platzhalter beliebiges stehen kann, kann ich das dann auch ersetzen bzw. wie?
Vielen Dank!!
lg

Code: Alles auswählen

<root>
    <mytag type="myType" myID="link://beliebig" />
</root>

wanne
Moderator
Beiträge: 7552
Registriert: 24.05.2010 12:39:42

Re: Parsen und ersetzen eines Wortes

Beitrag von wanne » 13.03.2013 17:02:08

Code: Alles auswählen

sed 'myID=\"link:\/\/.*\"/myID=\"link:\/\/10\.11\.12\.13\"/g'
Zuletzt geändert von wanne am 13.03.2013 17:05:44, insgesamt 2-mal geändert.
rot: Moderator wanne spricht, default: User wanne spricht.

Generic1
Beiträge: 78
Registriert: 15.11.2012 13:41:28

Re: Parsen und ersetzen eines Wortes

Beitrag von Generic1 » 13.03.2013 17:02:44

Also ich habs jetzt selber versucht, wenn folgendes dasteht, dann funkts:

Code: Alles auswählen

<mytag type="myType" myID="link://beliebig" />
mit

Code: Alles auswählen

sed -i 's/myID=\"link:\/\/[a-z]*/myID=\"link\/\/10\.11\.12\.13/g' alt.txt
das porblem ist, wenn es schon mal ersetzt wurde und das dasteht:

Code: Alles auswählen

<mytag type="myType" myID="link://10.11.12.13" />
dann weiß ich nicht genau, was ich da reinschreiben muss:

Code: Alles auswählen

sed -i 's/myID=\"link:\/\/[a-z]*  da gehört noch her [1-9]* und Punkte - das weiß ich leider nicht mit den Punkten      /myID=\"link\/\/10\.11\.12\.13/g' alt.txt
Wäre euch noch sehr dankbar für hilfe,
Vielen Dank,
lg
Generic1

wanne
Moderator
Beiträge: 7552
Registriert: 24.05.2010 12:39:42

Re: Parsen und ersetzen eines Wortes

Beitrag von wanne » 13.03.2013 17:05:34

s.o.
. Steht für ein beliebiges Zeichen.
Wobei du * vermutlich besser durch {3,20} ersetztst. (Dmait dir das nicht zu groß wird.)
Zuletzt geändert von wanne am 13.03.2013 17:08:23, insgesamt 1-mal geändert.
rot: Moderator wanne spricht, default: User wanne spricht.

Generic1
Beiträge: 78
Registriert: 15.11.2012 13:41:28

Re: Parsen und ersetzen eines Wortes

Beitrag von Generic1 » 13.03.2013 17:06:56

wanne hat geschrieben:

Code: Alles auswählen

sed -E 'myID=\"link:\/\/.*\"/myID=\"link:\/\/10\.11\.12\.13\"/g'

da schneidet er mir hinten den String ab bei

Code: Alles auswählen

<mytag type="myType" myID="link://beliebig" tag="asdfasdf" tag1="asdfsdaf"/>
das: tag="asdfasdf" tag1="asdfsdaf" ist dann nicht mehr da?

wanne
Moderator
Beiträge: 7552
Registriert: 24.05.2010 12:39:42

Re: Parsen und ersetzen eines Wortes

Beitrag von wanne » 13.03.2013 17:12:31

K machen wir sauberer:

Code: Alles auswählen

sed -E 's/myID="link:\/\/[^"]*"/myID="link:\/\/10\.11\.12\.13"/g'
^ steht für alle Zeichen außer den Nachfolgenden.
Anmerkung habe die \ vor den " entfernt. uname war da irgendwie doppelt vorsichtig zuerst ' und dann nochmal \. Da reicht eins aus.
rot: Moderator wanne spricht, default: User wanne spricht.

Liffi
Beiträge: 2345
Registriert: 02.10.2004 01:33:05

Re: Parsen und ersetzen eines Wortes

Beitrag von Liffi » 13.03.2013 17:49:33

Ich werfe mal xmlstarlet in den Raum ohne direkt eine Lösung anzubieten.
Regex sind nichts für XML. Es kann funktionieren, aber ich würde mich nicht darauf verlassen.
Siehe auch dieser schöne Thread[1] bei Stackoverflow.

[1]http://stackoverflow.com/questions/1732 ... ained-tags

wanne
Moderator
Beiträge: 7552
Registriert: 24.05.2010 12:39:42

Re: Parsen und ersetzen eines Wortes

Beitrag von wanne » 13.03.2013 21:32:33

@Liffi: Ich würde das so pauschal nicht sagen. sed regex können weit mehr als reguläre Sprachen beschreiben. (Sie können sogar Typ-0-Grammatiken Beschreiben.)
Und außerdem geht er von vorneherein davon aus korrektes XML (und vor allem XML, das einer bestimmten Form entspricht) zu bekommen und will das nicht überprüfen. Aus diesem heraus will man nur ein Bestimmtes Detail haben. Und das kann durchaus eine Reguläre sprache sein, bzw. durch einen Schnitt mit einer regulären sprache und der XML Sprache erreicht werden. (Ich würde sogar fast drauf wetten.)
Insbesondere bin ich mir sicher das man sich hier mit regex die fast immer tun begnügt.
rot: Moderator wanne spricht, default: User wanne spricht.

Liffi
Beiträge: 2345
Registriert: 02.10.2004 01:33:05

Re: Parsen und ersetzen eines Wortes

Beitrag von Liffi » 14.03.2013 07:30:21

wanne hat geschrieben:@Liffi: Ich würde das so pauschal nicht sagen. sed regex können weit mehr als reguläre Sprachen beschreiben. (Sie können sogar Typ-0-Grammatiken Beschreiben.)
Und außerdem geht er von vorneherein davon aus korrektes XML (und vor allem XML, das einer bestimmten Form entspricht) zu bekommen und will das nicht überprüfen. Aus diesem heraus will man nur ein Bestimmtes Detail haben. Und das kann durchaus eine Reguläre sprache sein, bzw. durch einen Schnitt mit einer regulären sprache und der XML Sprache erreicht werden. (Ich würde sogar fast drauf wetten.)
Insbesondere bin ich mir sicher das man sich hier mit regex die fast immer tun begnügt.
Ich will ja auch gar nicht bezweifeln, dass es funktionieren kann. Nur wollte ich dem Thread Ersteller nahelegen, bei xml an einen Parser und nicht an Regex zu denken :-). Fürs nächste Mal.

Btw.

Code: Alles auswählen

xmlstarlet edit --update "//*[@myID='link://platzhalter']/@myID" --value "link://10.11.12.13" test.xml
liest sich für mich auch ein wenig sauberer als die reguläre Expression (unter der Prämisse, dass die xml test.xml heißt).

EDIT::
Unter der Annahme, dass du alle myIDs ändern möchtest:

Code: Alles auswählen

xmlstarlet edit --update "//*[@myID]/@myID" --value "link://10.11.12.13" test.xml

Generic1
Beiträge: 78
Registriert: 15.11.2012 13:41:28

Re: Parsen und ersetzen eines Wortes

Beitrag von Generic1 » 14.03.2013 09:02:58

wanne hat geschrieben:K machen wir sauberer:

Code: Alles auswählen

sed -E 's/myID="link:\/\/[^"]*"/myID="link:\/\/10\.11\.12\.13"/g'
^ steht für alle Zeichen außer den Nachfolgenden.
Anmerkung habe die \ vor den " entfernt. uname war da irgendwie doppelt vorsichtig zuerst ' und dann nochmal \. Da reicht eins aus.

Besten Dank!!! - das wars.
lg
Generic1

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: Parsen und ersetzen eines Wortes

Beitrag von Cae » 14.03.2013 12:28:08

wanne hat geschrieben:K machen wir sauberer:

Code: Alles auswählen

sed -E 's/myID="link:\/\/[^"]*"/myID="link:\/\/10\.11\.12\.13"/g'
Verbesserung:

Code: Alles auswählen

$ sed -E 's,myID="link://[^"]*",myID="link://10.11.12.13",g'
Ich habe s/// durch s,,, ersetzt, damit man ein paar mal weniger escapen muss. Ausserdem braucht's keine \. im rechten Teil, das ist keine RegEx und wird nicht interpretiert. Da kann ein beliebiger String stehen, solange a) nicht der s-Trenner (also / bzw. ,) oder b) eine Referenz der Form \0, \1... \9 unescapt drin vorkommt.

Damit ist die Geschichte schon fast so uebersichtlich wie Liffis xmlstarlet (welches allerdings zuverlaessiger sein sollte und nicht unbewusst die XML-Struktur schrotten wird).

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Generic1
Beiträge: 78
Registriert: 15.11.2012 13:41:28

Re: Parsen und ersetzen eines Wortes

Beitrag von Generic1 » 14.03.2013 17:07:22

Besten Dank, also ich habs jetzt mit

Code: Alles auswählen

sed -E 's/myID="link:\/\/[^"]*"/myID="link:\/\/10\.11\.12\.13"/g'
gemacht und klappt auch ganz gut. Jetzt kommt aber der Oberhammer. Ich möchte das Ganze mit perl ausführen, und zwar:

Code: Alles auswählen

my $command = sed -E 's/myID="link:\/\/[^"]*"/myID="link:\/\/10\.11\.12\.13"/g';
system(command);
Da hab ich natürlich ziemliche Probleme mit den ' und ".
Weiß jemand wie ich das auf die schnelle hinbekomme - (leider bracuh ich das so - is so vorgegeben - wenig perl - viel shell schript verwenden)

Besten Dank!!
lg
Generic1

Generic1
Beiträge: 78
Registriert: 15.11.2012 13:41:28

Re: Parsen und ersetzen eines Wortes

Beitrag von Generic1 » 14.03.2013 17:08:01

Generic1 hat geschrieben:Besten Dank, also ich habs jetzt mit

Code: Alles auswählen

sed -E 's/myID="link:\/\/[^"]*"/myID="link:\/\/10\.11\.12\.13"/g'
gemacht und klappt auch ganz gut. Jetzt kommt aber der Oberhammer. Ich möchte das Ganze mit perl ausführen, und zwar:

Code: Alles auswählen

my $command = sed -E 's/myID="link:\/\/[^"]*"/myID="link:\/\/10\.11\.12\.13"/g';
system(command);
Da hab ich natürlich ziemliche Probleme mit den ' und ".
Weiß jemand wie ich das auf die schnelle hinbekomme, das mit den Anführungszeichen? - (leider bracuh ich das so - is so vorgegeben - wenig perl - viel shell schript verwenden)

Besten Dank!!
lg
Generic1

Liffi
Beiträge: 2345
Registriert: 02.10.2004 01:33:05

Re: Parsen und ersetzen eines Wortes

Beitrag von Liffi » 14.03.2013 19:00:06

Generic1 hat geschrieben: gemacht und klappt auch ganz gut. Jetzt kommt aber der Oberhammer. Ich möchte das Ganze mit perl ausführen, und zwar:
Da hab ich natürlich ziemliche Probleme mit den ' und ".
Weiß jemand wie ich das auf die schnelle hinbekomme - (leider bracuh ich das so - is so vorgegeben - wenig perl - viel shell schript verwenden)
Mit q oder qq. Musst du mal schauen, was dir mehr zusagt.

Antworten