Unter Linux filtern

Multimedia pur!
Benutzeravatar
Mic
Adventure-Gott
Adventure-Gott
Beiträge: 4604
Registriert: 28.08.2003, 16:23
Wohnort: Exil-Osnabrücker
Kontaktdaten:

Unter Linux filtern

Beitrag von Mic »

Ich habe eine (recht große) XML-Datei, in der unter anderem folgendes zu finden ist:

Code: Alles auswählen

<ansprechpartner>Herr XYZ</ansprechparner>
. Nun möchte ich mir die jeweiligen Inhalte in eine externen Datei speichern. Mein Versuch mit

Code: Alles auswählen

cat datei.xml | grep <ansprechpartner>*</ansprechparner> > liste
scheiterte natürlich kläglich, da mir grep gleich die gesamte Zeile raushaut, anstatt nur das gesuchte.

Nun bin ich blockiert und komme auf keinen grünen Zweig. Wie schaffe ich es, dass die Inhalte in einer externen Datei gespeichert werden? Am besten noch mit Suchen und Ersetzen (&uuml; -> ü)?
Wenn Vergangenheit, Gegenwart und Zukunft nichts weiter sind als verlorene Ideen aus einer anderen Ära,
etwa wie Boote auf einem ausgetrockneten See, dann ist die Beendigung eines Prozesses nie zu definieren.
Benutzeravatar
BENDET
Riesiger Roboteraffe
Riesiger Roboteraffe
Beiträge: 7475
Registriert: 20.03.2006, 08:48
Wohnort: Großraum Stuttgart
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von BENDET »

Meiner Meinung gar nicht.
Grep gibt immer die gesamte Zeile aus, siehe auch http://man.cx/grep(1)/de.

Für deinen Fall würde ich die Anfertigung eines Perl- oder Shell-Scirpts empfehlen, das die entsprechende Linie als String extrahiert und diesen dann modifiziert. Schließlich weißt du ja, wie dieser String aussieht.

Dafür sollten sich im Netz auch massenhaft Vorlagen finden lassen, die du entsprechend anpassen kannst.

Falls es sich um eine einmalige Angelegenheit handelt und kein automatisiertes Verfahren erforderlich ist, würde ich die Datei einfach nur mit einen Texteditor nachbearbeiten und alle

Code: Alles auswählen

"<ansprechpartner>"
bzw.

Code: Alles auswählen

"</ansprechpartner>"
durch ersetzen.

Ist aber ein interessantes Problem, das immer mal wieder jemand hat. Kann mir eigentlich nicht vorstellen, dass sich da bisher niemand eine allgemeine Lösung für geschrieben hat.

Vielleicht kann man da mal bei entsprechender Zeit was machen.
Rulaman
Hobby-Archäologe
Hobby-Archäologe
Beiträge: 133
Registriert: 25.09.2004, 18:13

Re: Unter Linux filtern

Beitrag von Rulaman »

Benutzeravatar
Mic
Adventure-Gott
Adventure-Gott
Beiträge: 4604
Registriert: 28.08.2003, 16:23
Wohnort: Exil-Osnabrücker
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von Mic »

Rulaman hat geschrieben:Versuchs mal mit sed
Hatte ich vorhin auch unter Beobachtung, aber arbeitet auch zeilenweise.
BENDET hat geschrieben:Dafür sollten sich im Netz auch massenhaft Vorlagen finden lassen, die du entsprechend anpassen kannst.
Und daran scheitere ich derzeit: "linux datei durchsuchen ausgeben expressions" oder "bash datei vorkommen prüfen ausgeben" liefern vieles, aber auf Anhieb nicht das, was ich suche.
Wenn Vergangenheit, Gegenwart und Zukunft nichts weiter sind als verlorene Ideen aus einer anderen Ära,
etwa wie Boote auf einem ausgetrockneten See, dann ist die Beendigung eines Prozesses nie zu definieren.
Benutzeravatar
Hans
Adventure-Treff
Adventure-Treff
Beiträge: 10716
Registriert: 01.01.2002, 12:35
Wohnort: Nürnberg
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von Hans »

Teillösung: Die Ersetzung mit Umlauten kannst du einfach mit ":% s/&uuml;/ü/g" (erster String wird global durch zweiten (hier: ü) ersetzt) im vi machen.

"<ansprechpartner>Herr XYZ</ansprechparner>" steht also nicht allein in der jewiligen Zeile? Gibt es sonst Charakteristiken? Steht das z.B. immer am Anfang der Zeile?
td
Süßwasserpirat
Süßwasserpirat
Beiträge: 344
Registriert: 26.07.2006, 03:57
Wohnort: Dresden-Südvorstadt

Re: Unter Linux filtern

Beitrag von td »

Das feine Manual lesen, “-o” finden und freuen.

Code: Alles auswählen

grep -o '<ansprechpartner>.*</ansprechpartner>' test.xml | sed -e 's~</\?ansprechpartner>~~g'
I will not be broken, though I am the one that bleeds.
Benutzeravatar
Mic
Adventure-Gott
Adventure-Gott
Beiträge: 4604
Registriert: 28.08.2003, 16:23
Wohnort: Exil-Osnabrücker
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von Mic »

Liefert mir wieder nur die kompletten Zeilen.
Hans hat geschrieben:"<ansprechpartner>Herr XYZ</ansprechparner>" steht also nicht allein in der jewiligen Zeile? Gibt es sonst Charakteristiken? Steht das z.B. immer am Anfang der Zeile?
Leider nein. Das XML ist so bescheiden aufgebaut, dass es manchmal für sich alleine steht, manchmal in einer Zeile mit anderen Elementen, manchmal nicht vorkommt..
Wenn Vergangenheit, Gegenwart und Zukunft nichts weiter sind als verlorene Ideen aus einer anderen Ära,
etwa wie Boote auf einem ausgetrockneten See, dann ist die Beendigung eines Prozesses nie zu definieren.
td
Süßwasserpirat
Süßwasserpirat
Beiträge: 344
Registriert: 26.07.2006, 03:57
Wohnort: Dresden-Südvorstadt

Re: Unter Linux filtern

Beitrag von td »

Mic hat geschrieben:Liefert mir wieder nur die kompletten Zeilen.
Dann machst du was falsch:

Code: Alles auswählen

mmarx@delacroix (548) t % cat test.xml 
foo bar <ansprechpartner>Herr XYZ</ansprechpartner> quux
mmarx@delacroix (549) t % grep -o '<ansprechpartner>.*</ansprechpartner>' test.xml | sed -e 's~</\?ansprechpartner>~~g'
Herr XYZ                  
mmarx@delacroix (550) t %
I will not be broken, though I am the one that bleeds.
Benutzeravatar
Mic
Adventure-Gott
Adventure-Gott
Beiträge: 4604
Registriert: 28.08.2003, 16:23
Wohnort: Exil-Osnabrücker
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von Mic »

Es kann durchaus sein (und wie ich gerade gesehen habe, ist das meistens der Fall), dass mehrere Ansprechpartner sich in einer Zeile befinden:

Code: Alles auswählen

cat test.xml
foo bar <ansprechpartner>Herr XYZ</ansprechpartner> quuxfoo bar <ansprechpartner>Herr 1</ansprechpartner> quux
foo bar <ansprechpartner>Herr 2</ansprechpartner> quux
grep -o '<ansprechpartner>.*</ansprechpartner>' test.xml | sed -e 's~</\?ansprechpartner>~~g'
Herr XYZ quuxfoo bar Herr 1
Herr 2
Wenn Vergangenheit, Gegenwart und Zukunft nichts weiter sind als verlorene Ideen aus einer anderen Ära,
etwa wie Boote auf einem ausgetrockneten See, dann ist die Beendigung eines Prozesses nie zu definieren.
Benutzeravatar
DasJan
Adventure-Treff
Adventure-Treff
Beiträge: 14683
Registriert: 17.02.2002, 17:34
Wohnort: London
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von DasJan »

Alle Zeilenumbrüche raushauen und dann nach jedem "</ansprechpartner>" wieder einen rein?

Das Jan
"If you are the smartest person in the room, you are in the wrong room."
perfektopheles

Re: Unter Linux filtern

Beitrag von perfektopheles »

Für solche Zwecke gibt es XSLT. Beispiel (ist ein Tutorial): http://www.w3schools.com/xsl/xsl_transformation.asp
(dann die XML-Datei z.B. einfach im Browser öffnen)
Benutzeravatar
Mic
Adventure-Gott
Adventure-Gott
Beiträge: 4604
Registriert: 28.08.2003, 16:23
Wohnort: Exil-Osnabrücker
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von Mic »

DasJan hat geschrieben:Alle Zeilenumbrüche raushauen und dann nach jedem "</ansprechpartner>" wieder einen rein?
Yep, gestern Nacht bin ich aufgewacht und ebenfalls auf diese naheliegende Idee gekommen. Werde also mittels sed und Suchen/Ersetzen nach jedem </ansprechpartner> einen Zeilenumbruch einfügen, gleichzeitig die Umlaute verschönern und dann mittels Dons Grep-Methode die Inhalte ziehen.
perfektopheles hat geschrieben:Für solche Zwecke gibt es XSLT.
Zusätzliche Software wollte ich eigentlich vermeiden. Sowie mehrere Schritte, die ich händisch anstoßen müsste. Bei der obigen Lösung reicht eine einfach Batch-Datei um ein Ergebnis zu erzielen. Bin eben faul. ;)



Auch wenn das Problem nun gelöst ist, würde mich trotzdem (aus reinem Lerneffekt) interessieren, ob es mit grep nicht auch möglich ist, die Inhalte so zu ziehen, dass der zusätzliche Weg über das Zeilenumbruch-Einfügen nicht notwendig ist.
Wenn Vergangenheit, Gegenwart und Zukunft nichts weiter sind als verlorene Ideen aus einer anderen Ära,
etwa wie Boote auf einem ausgetrockneten See, dann ist die Beendigung eines Prozesses nie zu definieren.
perfektopheles

Re: Unter Linux filtern

Beitrag von perfektopheles »

Mic hat geschrieben:
perfektopheles hat geschrieben:Für solche Zwecke gibt es XSLT.
Zusätzliche Software wollte ich eigentlich vermeiden. Sowie mehrere Schritte, die ich händisch anstoßen müsste. Bei der obigen Lösung reicht eine einfach Batch-Datei um ein Ergebnis zu erzielen. Bin eben faul. ;)
XSLT ist keine zusätzliche Software, das beherrscht fast jeder Browser, da braucht man kein Linux für ;) Die XSL Style Sheets sind ähnlich wie Batch-Dateien, nur dass sie genau für XML gedacht sind und die XML-Struktur berücksichtigen 8)
Außerdem klingt die grep+Suchen/Ersetzen-Methode nicht sehr händisch.
td
Süßwasserpirat
Süßwasserpirat
Beiträge: 344
Registriert: 26.07.2006, 03:57
Wohnort: Dresden-Südvorstadt

Re: Unter Linux filtern

Beitrag von td »

Code: Alles auswählen

mmarx@delacroix (559) t % cat test.xml
foo bar <ansprechpartner>Herr ZYX</ansprechpartner> quux
foo bar <ansprechpartner>Herr XYZ</ansprechpartner> quuxfoo bar <ansprechpartner>Herr 1</ansprechpartner> quux
mmarx@delacroix (560) t % grep -o '<ansprechpartner>[^<]*</ansprechpartner>' test.xml | sed -e 's~</\?ansprechpartner>~~g'
Herr ZYX                  
Herr XYZ
Herr 1
mmarx@delacroix (561) t %
Geht kaputt, wenn im Ansprechpartner-Tag ein „<“ auftaucht, aber sollte sonst passen.
Wenn du ein grep mit PCRE-Support (“grep -P”) hast, kannst du da auch non-greedy matchen (“.*?” statt “.*”), da tritt dann dieses Problem nicht auf.
I will not be broken, though I am the one that bleeds.
Benutzeravatar
Mic
Adventure-Gott
Adventure-Gott
Beiträge: 4604
Registriert: 28.08.2003, 16:23
Wohnort: Exil-Osnabrücker
Kontaktdaten:

Re: Unter Linux filtern

Beitrag von Mic »

Klasse, dank dir! Ich muss mich mal dringend mit regulären Ausdrücken beschäftigen, aber bisher hat es noch nicht >Klick< gemacht.
perfektopheles hat geschrieben:XSLT ist keine zusätzliche Software, das beherrscht fast jeder Browser.
Und der Browser ist für mich zusätzliche Software. Mit der Bash-Lösung brauche ich nun nichts weiter, als einen Befehl einzugeben und der Rest wird völlig automatisch erledigt. Mittels einem Cronjob brauche ich noch nicht mal das Programm händisch zu starten. Es wird einmal im Monat automatisch gestartet, holt sich die XML-Datei, verarbeitet sie, verschickt das Resultat per Mail.

Das habe ich schon immer an Linux geliebt. Für jemanden, der zu faul für stupide Arbeiten ist, das ideale Betriebssystem. :)
Wenn Vergangenheit, Gegenwart und Zukunft nichts weiter sind als verlorene Ideen aus einer anderen Ära,
etwa wie Boote auf einem ausgetrockneten See, dann ist die Beendigung eines Prozesses nie zu definieren.
Antworten