Text an Datei (xml) anfügen mit awk, sed, perl oder Ähnlichem...

S

Schlaubi_fi.de

Mac OS X User
Hallo,

nun habe ich auch mal ein Problem :D
Und zwar habe ich z.B. solch eine Datei:

Code:
<?xml version="1.0" ?>
<message xmlns:test="http://www.xxx.de/test"
         xmlns:new-val="http://www.xxx.de/new-value"
         xmlns:new-fct="http://www.xxx.de/new-fct">

  <commands currentstep="0">
    <command target="XMLQuery" method="qbe" key="xmlquery"/>
    <command target="client"/>
    <command target="XMLQuery" method="upd-check" key="xmlquery"/>
  </commands>

  <xmlquery encoding="UTF-8" optimize-type="joinmerge"
             schema="test" db-service="jdbc/test"
             in-slot=""  in-key="parties"
             out-slot="" out-key="parties">
    <pathstep name="party">
    </pathstep>
  </xmlquery>

  <parties>
    <party id="@PARTYID@"/>
  </parties>

</message>

Bei dem Element 'message' soll das Attribut revision="$Revision$" dazu,
also:

Code:
<?xml version="1.0" ?>
<message xmlns:test="http://www.xxx.de/test"
         xmlns:new-val="http://www.xxx.de/new-value"
         xmlns:new-fct="http://www.xxx.de/new-fct" [b]revision="$Revision$"[/b]>

  <commands currentstep="0">
    <command target="XMLQuery" method="qbe" key="xmlquery"/>
    <command target="client"/>
    <command target="XMLQuery" method="upd-check" key="xmlquery"/>
  </commands>

  <xmlquery encoding="UTF-8" optimize-type="joinmerge"
             schema="test" db-service="jdbc/test"
             in-slot=""  in-key="parties"
             out-slot="" out-key="parties">
    <pathstep name="party">
    </pathstep>
  </xmlquery>

  <parties>
    <party id="@PARTYID@"/>
  </parties>

</message>

Jetzt habe ich das Problem, dass ich nicht nur eine sondern mehrer solcher Dateien habe in denen ich revision="$Revision$" hinzufügen möchte, nur leider lautet das erste Element nicht immer 'message' und außerdem ist es nicht immer auf 3 Zeilen aufgeteilt.

Deshalb klappt auch mein erster Ansatz nur für genau diese Datei, aber eben nicht allgemein:
Code:
perl -wne '/<message/ and do { print; $_=<>; print; $_=<>; s/>/
revision="\$Revision\$">/; print;  next; }; print;' x.xml

Irgendwelche Ideen? :(

//NACHTRAG:
Die Datei kann auch z.B. wie folgt aufgebaut sein:
Code:
<?xml version="1.0" ?>
<message>
  <commands currentstep="0">
    <command target="ScriptletManager" method="gc" scriptlet="admin.GC"/>
  </commands>
</message>

Das soll daraus werden:
Code:
<?xml version="1.0" ?>
<message [b]revision="$Revision$"[/b]>
  <commands currentstep="0">
    <command target="ScriptletManager" method="gc" scriptlet="admin.GC"/>
  </commands>
</message>
 
So etwa?

Code:
perl -ne '$t.=$_; END{$t=~s!(<message.*?)>!\1 revision="\$Revision\$">!sg; print $t}' x.xml

Gruss, Phorus
 
Hallo

Wenn die Dateien nicht so groß sind (mehrere MB), dann geht auch sowas:
Code:
perl -0\777 -pe 's/(<message[^>]+?)>/$1 revision="\$REVISION\$">/g' Datei
File Slurp ;)
Gruß Wolfgang
PS Wer ist eigentlich dieser Phorus? :devil:
 
Code:
...[^>]+?)...

Damit erschlägst Du nicht den Fall <message>, aber ansonsten hast Du wieder die kürzeste Lösung gefunden...grrr ;)

PS Wer ist eigentlich dieser Phorus?

Arg, verdammte Gewohnheit ;)
 
Zuletzt bearbeitet:
Nennt ihr euch alle zur Verwirrung der User um (Karneval ist doch vorbei)? :D
 
Xanti schrieb:
Code:
...[^>]+?)...

Damit erschlägst Du nicht den Fall <message>, aber ansonsten hast Du wieder die kürzeste Lösung gefunden...grrr ;)
Aber damit:
Code:
perl -0\777 -pe 's/(<message[^>][color=red]*[/color]?)>/$1 revision="\$REVISION\$">/g' liste
Xanti schrieb:
Arg, verdammte Gewohnheit ;)
Ausreden!
Wenn hier einer Alzheimer haben darf, dann ich.:D

Gruß Wolfgang ( der nur seine _1 verloren hat)
 
Wolfgang schrieb:
Aber damit:
Code:
perl -0\777 -pe 's/(<message[^>][color=red]*[/color]?)>/$1 revision="\$REVISION\$">/g' liste
...

Ich bin sogar so frech zu sagen, dass es auch ohne [^>] geht. ;)
 
Hallo @Phorus ähhm Xanti(ppe) :D
Xanti schrieb:
Ich bin sogar so frech zu sagen, dass es auch ohne [^>] geht. ;)
Ich seh, dass du stark im kommen bist, mir langsam die Puste ausgeht um gegenzuhalten...
Aber euer Ehren, hier irrt ihr.:devil:
Das geht so nur im Falle von <message>

Du darfst trotzdem weiter frech sein.
:D
Gruß Wolfgang
 
Arg, hab übersehen, dass Du nicht den /s-Schalter beim Substitute getätigt hast. ".*?../s" statt "[^>]*?" ist trotzdem kürzer :D
 
Hallo
Xanti schrieb:
Arg, hab übersehen, dass Du nicht den /s-Schalter beim Substitute getätigt hast. ".*?../s" statt "[^>]*?" ist trotzdem kürzer :D
Mit welcher Datei hast du das erfolgreich getestet?
cat liste
<?xml version="1.0" ?>
<message xmlns:test="http://www.xxx.de/test"
xmlns:new-val="http://www.xxx.de/new-value"
xmlns:new-fct="http://www.xxx.de/new-fct">

<commands currentstep="0">
<command target="XMLQuery" method="qbe" key="xmlquery"/>
<command target="client"/>
<command target="XMLQuery" method="upd-check" key="xmlquery"/>
</commands>

<xmlquery encoding="UTF-8" optimize-type="joinmerge"
schema="test" db-service="jdbc/test"
in-slot="" in-key="parties"
out-slot="" out-key="parties">
<pathstep name="party">
</pathstep>
</xmlquery>

<parties>
<party id="@PARTYID@"/>
</parties>

</message>
Code:
perl -0\777 -pe 's/(<message*?)>/$1 revision="\$REVISION\$">/sg' list
<?xml version="1.0" ?>
<message xmlns:test="http://www.xxx.de/test"
         xmlns:new-val="http://www.xxx.de/new-value"
         xmlns:new-fct="http://www.xxx.de/new-fct">

        <commands currentstep="0">
        <command target="XMLQuery" method="qbe" key="xmlquery"/>
        <command target="client"/>
        <command target="XMLQuery" method="upd-check" key="xmlquery"/>
        </commands>

        <xmlquery encoding="UTF-8" optimize-type="joinmerge"
                schema="test" db-service="jdbc/test"
                in-slot=""  in-key="parties"
                out-slot="" out-key="parties">
                        <pathstep name="party">
                        </pathstep>
        </xmlquery>

        <parties>
                <party id="@PARTYID@"/>
        </parties>

    </message>
???
:brav: duck und wech
Gruß Wolfgang
PS Warum ist mein CODE-Bereich immer so schmal?
 
Das geht schon, Du hast den "." vor "*?" vergessen ;)

edit: "." geht natürlich unter, wenn man ... als umgangssprachlichen Terminus ebenfalls im Code benutzt, ... meine Schuld ;)
 
Zuletzt bearbeitet:
Xanti schrieb:
Das geht schon, Du hast den "." vor "*?" vergessen ;)

Jo, das ist latürnich etwas anderes.
:think:
Damit sind wir auf den Punkt gekommen.
Ich gebe mich geschlagen.

Gruß Wolfgang
PS Wie beim Sport:
Du legst was vor, ich übertreff es und du legst noch einen daruf.
Ergo bist du auf dem Treppchen
Gratulation!
8)
 
Zuletzt bearbeitet:
Ja waaaaaaahnsinn!!!...da haut's mich doch glatt vom Hocker,
vielen vielen Dank bis hier her schon einmal :))

Der Code funktioniert:
Code:
perl -0\777 -pe 's/(<message.*?)>/$1 revision="\$Revision\$">/sg' list

Jetzt habe ich nur noch 2 Problemchen...

1. Das erste Element nach dem Root-Element (gekennzeichnet mit <?xml version="1.0" ?>) muss nicht umbedingt 'message' heißen

2. Bei dem obigen Code wird hinter jedes in 'list' vorkommende <message> (was jedoch auch anders heißen kann) das $Revision$ geschrieben, dies sollte jedoch nur beim ersten Element (egal wie es heißt) passieren, das nach dem Root-Element kommt also nach <?xml version="1.0" ?>


Also ich bin ja jetzt schon überglücklich und völlig aus dem Häuschen, weil das ziemlich viel Zeit erspart bei ca. 500 Dateien, also wenn das nicht machbar ist dann muss ich halt in den sauren Apfel beißen und es manuell machen, schonmal vielen Dank im Voraus!!! :))

PS: Natürlich habe ich mir auch meine Gedanken gemacht, aber sowas z.B.:
Code:
perl -0\777 -pe 's/(<.*?)>/$1 revision="\$Revision\$">/sg' list
löst auch noch keines meiner Probleme, da es hierbei hinter jedes Element setzt, soll aber nur nach dem ersten Element, dass nach dem Root-Element kommt stehen...ich hoffe es ist verständlich was gemeint ist.
 
Zuletzt bearbeitet:
Bitte schön :)

Code:
perl -0\000 -pe 's/(<\?xml version="1.0" \?>\n<.*?)>/$1 revision="\$Revision\$">/sg' xml

@Wolfgang: Hab gerade gesehen, dass bei "-0\000" keine Grössenbeschränkung besteht, jedenfalls hab ichs gerade an einem 500 MB-File getestet.
 
Xanti schrieb:
Klasse, vielen Dank! Klappt prima.

Wenn mir jetzt noch Jemand als i-Tüpfelchen das Kommando erklären kann bin ich noch glücklicher als ich es ohnehin schon bin :D
Code:
perl -0\000 -pe 's/(<\?xml version="1.0" \?>\n<.*?)>/$1 revision="\$Revision\$">/sg' xml
Also in etwa habe ich eine Ahnung..ein 'einfaches' suchen/ersetzen...aber genau? :think:
 
Code:
perl -0\000 -pe 's/(<\?xml version="1.0" \?>\n<.*?)>/$1 revision="\$Revision\$">/sg' xml

-0\000 .. xml wird als ein grosser String eingelesen.

Der Rest ist ein simpler Substitutebefehl:

s/muster/replace/sg

/sg bedeutet: s... "." matcht auch "\n"
g... Ersetze so oft wie möglich

$1 entspricht dem erkannten Text, der mit () umschlossen ist.
 
Xanti schrieb:
Bitte schön :)


@Wolfgang: Hab gerade gesehen, dass bei "-0\000" keine Grössenbeschränkung besteht, jedenfalls hab ichs gerade an einem 500 MB-File getestet.

Was passiert, wenn du das mit vielen Dateien solcher Größe machst?
Oder wenn die Hardware nur 256MB zur Verfügung hat?

:oldman

Es geht dabei nicht um eine Beschränkung der Dateigröße, sondern um Performance.

Wenn du damit versuchst eine Datei mit 500MB am Stück einzulesen, wird es - abhängig vom verfügbaren Speicher - langsamer werden.
Wenn dann sowas z.B. als Webanwendung oder Cronjob mit kurzem Zyklus läuft, kann es dann zu Problemen kommen. Generell ist deshalb eine zeilenweise Verarbeitung vorzuziehen. Besonders wenn nicht sichergestellt werden kann, dass die Filesize nicht zu groß werden kann.

Gruß Wolfgang
 
Aaaah super, dann hab ich das jetzt auch verstanden.
Was ich mich dennoch frage, wozu denn das ? benötigt:

perl -0\000 -pe 's/(<\?xml version="1.0" \?>\n<.*?)>/$1 revision="\$Revision\$">/sg' xml


? bedeutet das letzte Zeichen muss einmal oder gar nicht auftreten - ist als letztes Zeichen > gemeint?
 
@ Wolfgang. yep, das macht Sinn.

Schlaubi_fi.de schrieb:
...
? bedeutet das letzte Zeichen muss einmal oder gar nicht auftreten - ist als letztes Zeichen > gemeint?

"?" bezieht sich auf ".*" ("." bedeutet beliebiges Zeichen, "*" bedeutet beliebig oft) und bedeutet "non greedy", sprich er fängt bei der Suche beim kleinst möglichen Text an, also "", und erweitert dann um jeweils ein Zeichen, bis er ">" erreicht hat.
 

Ähnliche Themen

NagiosGrapher 1.7.1 funktioniert nicht

Festplatte stirbt, dd funktioniert nicht

Displayport + externer Monitor zeigt bei startx nichts erst bei DVI

Ubuntu X / dbus problem

HP PSC 2175 - CUPS druckt nicht

Zurück
Oben