Frage zu grep! Wie kann ich den Teil eines Textes zwischen 2 bekannten Zeichen (">" und "<") ausgeben?

  • Hallo,
    ich versuche gerade aus einer html Datei mir einen Teil "herauszufischen"!
    Wie kann ich den Teil eines Textes zwischen 2 bekannten Zeichen (">" und "<") ausgeben? Wie kann ich das mit grep durchführen?


    Uwe

  • Hi,


    das geht so:

    Code
    1. echo "bla bla bla <p>Mein Text</p> bla bla bla" | sed "s|.*<p>\(.*\)</p>.*|\\1|"


    oder wenn es wirklich nur die Beiden Zeichen < und > sein sollen, dann halt so:

    Code
    1. echo "bla bla bla <p>Mein Text</p> bla bla bla" | sed "s|.*>\(.*\)<.*|\\1|"


    wenn aber mehrere <, > Zeichen in einer Zeile vorkommen muss der Ausdruck noch etwas genauer werden. Wenn Der Text mehrzeilig ist, musst Du zuvor die gewünschte Zeile per grep heraussuchen, z.B. so:

    Code
    1. echo "bla bla bla <p>Mein Text</p> bla bla bla" | grep "<p>" | sed "s|.*<p>\(.*\)</p>.*|\\1|"



    Claus

    MLD 5.1 mit vdr 2.2 - lirc yaUSBir - Octopus NET S2 - SCR - XFX GeForce 9300 mit Intel E3200 - 2GB RAM -
    WD Green 6TB HDD - SanDisk 64GB SSD - Lian Li PC-C37B - Samsung LE40A559
    MLD 5.3 mit vdr 2.3.4 - Raspberry Pi 3 - rpihddevice
    MLD 5.1 mit vdr 2.2 - Banana Pi - softhddevice
    MLD 5.0 mit Squeeze Play - Raspberry Pi 2 - 32GB SD - 7" Touch TFT
    MLD 2.0 mit vdr 1.6 - SMT-7020s - 80GB HDD

  • Zitat

    ich versuche gerade aus einer html Datei mir einen Teil "herauszufischen"!


    Ok, aber dafür solltest Du nicht grep nehmen.


    Perl wäre die erste Wahl, php und andere gehen aber auch.


    In einer HTML-Datei kann sich der gewünschte Text ja über mehrere Zeilen erstrecken ...
    Grep ist eher für zeilenbasierte Suche geeignet.


    Allerdings aufpassen mit den Suchmustern! Bei HTML können gleiche Tags ja geschachtelt vorkommen, also gut überlegen, was Du rausziehen möchtest.


    Gruß Gero

  • Macht man das nicht mit xslt?


    Funktioniert das nicht nur wenn die Webseiten fehlerfrei sind ;) Da würde ich jetzt erstmal spontan nicht von ausgehen.


    Wenn die Seite doch garantiert fehlerfrei ist dann wäre es vermutlich am einfachsten sich für die Sprache der Wahl nen brauchbaren HTML Parser zu schnappen, der bietet dann Direktzugriff auf alle Elemente.


    cu

  • Vielen Dank erstmal für die vielen Tipps! :) Gibt jetzt viel zu lesen...


    Gruß Uwe


    PS: Ich versuche den Text im Code Element einer Seite in der Konsole auszugeben. Dachte es geht einfacher, aber mit grep kommt man damit nicht zum Ziel. Mal schauen ....

    Dieser Beitrag wurde bereits 1 Mal editiert, zuletzt von Uwe ()


  • Funktioniert das nicht nur wenn die Webseiten fehlerfrei sind Da würde ich jetzt erstmal spontan nicht von ausgehen.


    Stimmt, hat oft nicht viel mit XML zu tun.


    Gerald


    HP Proliant MicroServer Gen8, Xeon E3-1230, 12 GB RAM, 3xWD red 2TB im RAID 5, 2xSundtek MediaTV Home DVB-C/T, L4M TWIN-C/T, Ubuntu Server 14.04.1, Plex Media Server
    Samsung UE55H6470

  • Der konkrete Anwendungsfall legt nicht unbedingt die Nutzung eines Regex als sinnvolle Lösung nahe. Das wird in der Praxis eh nicht funktionieren, es wird eher auf ein manuelles Nachschlagen hinauslaufen.


    EDIT: Ich muss mich korrigieren, das Posting wird wohl schon seit mehreren Jahren immer wieder an der gleichen Stelle aktualisiert.



    Gruß
    hepi

  • Der konkrete Anwendungsfall legt nicht unbedingt die Nutzung eines Regex als sinnvolle Lösung nahe. Das wird in der Praxis eh nicht funktionieren, es wird eher auf ein manuelles Nachschlagen hinauslaufen.


    Ich hatte heute ein wenig Zeit und fand meine Aufgabe gar nicht schlecht! :D Ich bleibe dran. :)

  • Ok, und nach dem ganzen rumgewurstel hier mit sed und xslt hier nun mal der saubere Oneliner :-)


    Code
    1. $ echo 'foo>test</bar' | grep -Po '(?<=>)[^<]+(?=<)'


    • -P: Perl-compatible regular expression
    • -o: Only matching part
    • (?<=>): string preceded by '>' (look behind)
    • [^<]+: any character but <
    • (?=<): string followed by '<' (look ahead)


    Und falls es nur der erste Match sein soll, füge noch ein '-m1' hinzu. Ich finde ja, dass look ahead und look behind viel zu wenig Beachtung finden :)


    Edit: Falls der gesuchte String über mehrere Zeilen verteilt sein kann, hilft noch ein zusätzliches '-z' in den grep-Optionen


    Edit 2 @ Hepi: Die [code]-Umgebung und ein Copy&Paste-Fehler hat mir die Syntax kaputt gemacht :) Habs korrigiert, danke für den Hinweis!

  • Cybso hat den entscheidenden Hinweis mit look ahead und look behind gegeben. Leider hat er seinen String aber syntaktisch falsch gepostet oben. EDIT: Mittlerweile korrigiert.
    Richtig ist:

    Code
    1. echo '<foo>test</bar>' | grep -Po '(?<=>)[^<]+(?=<)'


    Und das hier löst das Problem:

    Code
    1. wget -O - "http://www.die-url-die-Uwe-oben-wieder-geloescht-hat.com | grep -Po '(?<=codecontent\">)[^<]+(?=<\/div>)'


    EDIT: Uwe, war Dir die URL zu heiß? Hast Du sie wieder gelöscht aus Deinem Posting?


    Gruß
    hepi

  • Cybso hat den entscheidenden Hinweis mit look ahead und look behind gegeben. Leider hat er seinen String aber syntaktisch falsch gepostet oben. EDIT: Mittlerweile korrigiert.
    Richtig ist:

    Code
    1. echo '<foo>test</bar>' | grep -Po '(?<=>)[^<]+(?=<)'


    Und das hier löst das Problem:

    Code
    1. wget -O - "http://www.die-url-die-Uwe-oben-wieder-geloescht-hat.com | grep -Po '(?<=codecontent\">)[^<]+(?=<\/div>)'


    EDIT: Uwe, war Dir die URL zu heiß? Hast Du sie wieder gelöscht aus Deinem Posting?


    Naja, ich wollte es allgemein halten, deswegen dachte ich, ich lösche diese wieder. Gern gesehen wird diese hier wohl auch nicht. ;)
    Sehr gut, damit klappt es, wobei ich die Web Seite erstmal zwischenspeichere und dann mit grep "bearbeite". Bei deinem Beispiel fehlt der 1. Buchstabe des Ergebnisses, wenn ich zwischenspeichere ist auch der 1. Buchstabe vorhanden, also "T-...."
    Ich bin begeistert, was man nicht alles mit einem 1 Zeiler machen kann. :D


    Vielen Dank!

  • XSLT hätte immerhin den Vorteil, dass verschachtelte Elemente, Zeichenreferenzen, usw. vergleichsweise einfach zu handhaben sind. Mit grep (bzw. sed) macht das echt keinen Spaß. ;)