sed-Filter <current_event>DATEN </current_event&a

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
K.I.T.T.
Beiträge: 104
Registriert: 14.11.2005 11:33:38

sed-Filter <current_event>DATEN </current_event&a

Beitrag von K.I.T.T. » 08.04.2006 21:09:50

Bsp.
<current_event>
Daten
Daten irgendwas
Daten 1231
</current_event>
<other>
irgendwas
</other>
<other2>
irgendwas
</other2>

Hi. Ich möchte gerne mit sed die Daten (nur) im current_event-Tag-Bereich aus einer etwas größere XML-Datei extrahieren, doch leider bekomme ich die Struktur nicht so recht hin.
Kann mir jm. da bitte weiterhelfen?

Wenn ich die SED-Doku richtig verstanden habe

müsste dieser Befehl so

Code: Alles auswählen

  sed 's/[^...]\&\<"<current_event>">\[...]\&\<"</current_event>">\[^...]/q;'  
aufgebaut sein, doch leider:

sed: -e expression #1, char 66: unknown option to `s'

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 08.04.2006 23:34:21

SED ist ja ein denkbar ungeeignetes Tool zum Parsen von XML Dokumenten.
Daher nehme ich mir die Freiheit heraus, dir ein kleines XSLT Beispiel vorzuführen:

Code: Alles auswählen

gms@gms1:~$ cat x.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:apply-templates select="//current_event"/>
</xsl:template>

<xsl:template match="current_event">
  <xsl:value-of select="text()"/>
</xsl:template>

</xsl:stylesheet>
gms@gms1:~$ xsltproc x.xsl x.xml

Daten
Daten irgendwas
Daten 1231
gms@gms1:~$ 
Gruß
gms

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 09.04.2006 08:22:24

Ich weiß nicht ob dir das hilft, aber so würde ich es in Perl lösen, wenn ich den XML-Parser nicht verwenden wollte.

Code: Alles auswählen

#!/usr/bin/perl
my $txt=$ARGV[0];
# Regulärer Ausfruck in einer Schleife
while($txt=~m|<current_event>[\s\r\n]*([^<>]+?)[\s\r\n]*</current_event>|s)
{
 $txt=$'; # alles vor und den gefundenen String löschen
 print "$1"; # Ausgeben was in den runden Klammern steht.
 print "\n*********\n"; # Trenner
}

K.I.T.T.
Beiträge: 104
Registriert: 14.11.2005 11:33:38

Beitrag von K.I.T.T. » 09.04.2006 12:00:20

Danke den beiden Vorschlägen.

Die letztere Variante scheint mir für meine Zwecke leichter zu Handhaben zu sein.
(besser gesagt, xsltproc ist in meiner SpezialDebianVersion nicht (mehr) möglich)

Meine Anpassung::
tagextract.pl "<a>" "</a>" "<a>damn</a>"

Code: Alles auswählen

#!/usr/bin/perl
my $filt1=$ARGV[0];
my $filt2=$ARGV[1];
my $txt=$ARGV[2];
# Regulärer Ausfruck in einer Schleife
while($txt=~m|$filt1[\s\r\n]*([^<>]+?)[\s\r\n]*$filt2|s)
{
        $txt=$'; # alles vor und den gefundenen String löschen
        print "$1"; # Ausgeben was in den runden Klammern steht.
}
So lässt sich damit noch viel mehr anstellen ;-)

Allerdings funktioniert es nicht mit Zeilenumbrüchen :-(

Gruß

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 09.04.2006 14:09:32

K.I.T.T. hat geschrieben:Allerdings funktioniert nicht es nicht mit Zeilenumbrüchen :-(
Wie meinst du das?

Übrigens wenn du nur nach "<...> ... </...>" Tags suchst ginge es auch so:

Code: Alles auswählen

#!/usr/bin/perl
my ($filt,$txt)=@ARGV;
# Regulärer Ausdruck in einer Schleife
while($txt=~m|<[^<>]*?$filt[^<>]*?>[\s\r\n]*([^<>]+?)[\s\r\n]*<[^<>]*?/[^<>]*?$filt[^<>]*?>|s)
{
        $txt=$'; # alles vor und den gefundenen String löschen
        print "$1"; # Ausgeben was in den runden Klammern steht.
}

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 09.04.2006 16:56:41

K.I.T.T. hat geschrieben:Die letztere Variante scheint mir für meine Zwecke leichter zu Handhaben zu sein.
(besser gesagt, xsltproc ist in meiner SpezialDebianVersion nicht (mehr) möglich)
und perl-xml Module wie z.B. "libxml-xpath-perl" hast du nicht in deiner "SpezielDebianVersion" ?

Code: Alles auswählen

gms@gms1:~$ cat x.pl
#!/bin/perl

use XML::XPath; # in Paket libxml-xpath-perl

foreach my $file (@ARGV) {
  my $xp = XML::XPath->new(filename => $file) or die "failed to read xml file '$file':$_";

  foreach my $event ($xp->find('//current_event')->get_nodelist){
    print $event->string_value;
  }
}
gms@gms1:~$ perl x.pl x.xml

Daten
Daten irgendwas
Daten 1231


Gruß
gms

K.I.T.T.
Beiträge: 104
Registriert: 14.11.2005 11:33:38

Beitrag von K.I.T.T. » 10.04.2006 12:20:57

ToPeG hat geschrieben:
K.I.T.T. hat geschrieben:Allerdings funktioniert nicht es nicht mit Zeilenumbrüchen :-(
Wie meinst du das?
Die Datenquelle verwendet irgeneinen ungewühnlichen Zeilenumbrauch.
Auf "\n" usw. spricht der scheinbar nicht an.

[quoite]
Übrigens wenn du nur nach "<...> ... </...>" Tags suchst ginge es auch so:

Code: Alles auswählen

#!/usr/bin/perl
my ($filt,$txt)=@ARGV;
# Regulärer Ausdruck in einer Schleife
while($txt=~m|<[^<>]*?$filt[^<>]*?>[\s\r\n]*([^<>]+?)[\s\r\n]*<[^<>]*?/[^<>]*?$filt[^<>]*?>|s)
{
        $txt=$'; # alles vor und den gefundenen String löschen
        print "$1"; # Ausgeben was in den runden Klammern steht.
}
[/quote]

So spart man sich ja noch ein paar Zeilen ;-)
Wird übernommen, thx.
Mit Perl hatte ich leider noch nicht so viel zu tun.



gms hat geschrieben:....
und perl-xml Module wie z.B. "libxml-xpath-perl" hast du nicht in deiner "SpezielDebianVersion" ?
Leider Nein.
Es handet sich um so eine Embedded-Debian-Version, die gerade noch auf das System (USB-Stick) drauf passt.



So. Aber nun muss ich erstmal zur Arbeit. Irgndwie muss der ganze Spaß ja auch finanziert werden.... ;-)


Gruß

Antworten