Anzeige:
Ergebnis 1 bis 10 von 10

Thema: Textstelle mit sed

  1. #1
    Ahnungsloser
    Registriert seit
    Aug 2002
    Beiträge
    335

    Textstelle mit sed

    Guten Tag,

    ich versuche schon seit Stunden einen bestimmten Text mit sed aus einer Zeile rauszuschneiden.


    Die Zeile lautet z.B.:

    <channel name='Pool Temperatur Wasser' ise_id='9432' bla='123'>

    Ich möchte, dass nach "name" gesucht wird und der Name innerhalb " ' " soll als Ausgabe erscheinen.

    Ich hoffe ihr könnt mir helfen.
    Vielen Dank.
    Gruß DR.Chris
    ka.homelinux.org

  2. #2
    Registrierter Benutzer Avatar von ThorstenHirsch
    Registriert seit
    Nov 2002
    Beiträge
    6.556
    So klappt's:
    Code:
    sed "s/.* name=\'\([^']*\)\'.*/\1/" xml_name.xml
    Eigentlich hätte ich gerne noch eine schönere Lösung mit xmllint angegeben, aber da ist's wohl nicht so einfach, einen xpath-Ausdruck mit mehreren Ausgaben zu verarbeiten. Je nachdem, was Du mit der Ausgabe machen willst, lohnt sich's vielleicht, in eine Skriptsprache zu wechseln.
    ¡Nuestro amigo... el Computador!

  3. #3
    Ahnungsloser
    Registriert seit
    Aug 2002
    Beiträge
    335
    Vielen Dank!
    Ich bekomme in der Konsole mit dem Befehl:
    echo "<channel name='Pool Temperatur Wasser' ise_id='9432' bla='123'>" | sed "s/.* name=\'\([^']*\)\'.*/\1/"

    diese Ausgabe:
    <channel name='Pool Temperatur Wasser' ise_id='9432' bla='123'>
    Gruß DR.Chris
    ka.homelinux.org

  4. #4
    Registrierter Benutzer Avatar von ThorstenHirsch
    Registriert seit
    Nov 2002
    Beiträge
    6.556
    Uff, bei mir erscheint nur:
    Pool Temperatur Wasser
    ...unter macOS. Aber unter Linux erhalte ich Deine Ausgabe (die bedeutet, dass bei sed das pattern nicht matcht). Na super, jetzt sind wir auf eine Inkompatibilität zwischen den beiden Versionen gestoßen. :-(

    Hm... naja, wenigstens ist meine erste Vermutung gleich die richtige, es liegt am escapten Anführungszeichen. Probier's nochmal hiermit:
    Code:
    echo "<channel name='Pool Temperatur Wasser' ise_id='9432' bla='123'>" | sed "s/.* name='\([^']*\)'.*/\1/"
    ¡Nuestro amigo... el Computador!

  5. #5
    Registrierter Benutzer Avatar von Huhn Hur Tu
    Registriert seit
    Nov 2003
    Ort
    Karlsruhe
    Beiträge
    2.243
    Sowas vielleicht
    Code:
    echo "<channel name='Pool Temperatur Wasser' ise_id='9432' bla='123'>" | grep -Eo name.* | grep -Eo ".*ise_id" | sed 's/ise_id//g' | sed 's/name=//g' | sed 's/\x27//g'
    
    Pool Temperatur Wasser
    Zwischen anonym sein wollen und seine Daten nicht verkaufen wollen, liegen zwei Welten. Wenn man sich einen kostenpflichtigen Dienst sucht, dann meist, weil man für diese Dienstleistung zahlt und nicht selbst das Produkt sein will.


  6. #6
    @SlopePointNZ Avatar von craano
    Registriert seit
    Jul 2004
    Beiträge
    1.313
    Ich gehe davon aus, dass das XML Tag in der Datei richtig abgeschlossen wurde, dann ginge es auch so:
    Code:
    echo "<channel name='Pool Temperatur Wasser' ise_id='9432' bla='123' />" |  xmlstarlet sel -t -v "/channel/@name"

  7. #7
    Ahnungsloser
    Registriert seit
    Aug 2002
    Beiträge
    335
    Vielen Dank für die vielen Vorschläge.

    echo "<channel name='Pool Temperatur Wasser' ise_id='9432' bla='123'>" | sed "s/.* name='\([^']*\)'.*/\1/"
    Das bringt mir tatsächlich das gewünschte Ergebnis.

    Aber ich muss wohl doch weiter ausholen, da es nicht ganz so gut klappt wie ursprünglich gedacht.

    Die Abfrage lautet z.B.:
    Die komplette Ausgabe:
    <state>
    <device name="Pool Temperaturen" ise_id="9401" unreach="false" sticky_unreach="false" config_pending="false">
    <channel name="Pool Temperaturen:0" ise_id="9402">
    <datapoint name="BidCos-RF.OEQ0801918:0.UNREACH" type="UNREACH" ise_id="9421" value="false" valuetype="2" valueunit="" timestamp="1571936610"/>
    <datapoint name="BidCos-RF.OEQ0801918:0.STICKY_UNREACH" type="STICKY_UNREACH" ise_id="9417" value="false" valuetype="2" valueunit="" timestamp="1571936610"/>
    <datapoint name="BidCos-RF.OEQ0801918:0.CONFIG_PENDING" type="CONFIG_PENDING" ise_id="9403" value="false" valuetype="2" valueunit="" timestamp="1571936610"/>
    <datapoint name="BidCos-RF.OEQ0801918:0.LOWBAT" type="LOWBAT" ise_id="9411" value="false" valuetype="2" valueunit="" timestamp="1572028647"/>
    <datapoint name="BidCos-RF.OEQ0801918:0.RSSI_DEVICE" type="RSSI_DEVICE" ise_id="9415" value="1" valuetype="8" valueunit="" timestamp="1571936610"/>
    <datapoint name="BidCos-RF.OEQ0801918:0.RSSI_PEER" type="RSSI_PEER" ise_id="9416" value="179" valuetype="8" valueunit="" timestamp="1571936610"/>
    <datapoint name="BidCos-RF.OEQ0801918:0.DEVICE_IN_BOOTLOADER" type="DEVICE_IN_BOOTLOADER" ise_id="9407" value="false" valuetype="2" valueunit="" timestamp="1571936610"/>
    <datapoint name="BidCos-RF.OEQ0801918:0.UPDATE_PENDING" type="UPDATE_PENDING" ise_id="9425" value="false" valuetype="2" valueunit="" timestamp="1571936610"/>
    </channel>
    <channel name="Pool Temperatur Heizung" ise_id="9429">
    <datapoint name="BidCos-RF.OEQ0801918:1.TEMPERATURE" type="TEMPERATURE" ise_id="9431" value="10.500000" valuetype="4" valueunit="°C" timestamp="1572028647"/>
    <datapoint name="BidCos-RF.OEQ0801918:1.LOWBAT" type="LOWBAT" ise_id="9430" value="false" valuetype="2" valueunit="" timestamp="1572028647"/>
    </channel>
    <channel name="Pool Temperatur Wasser" ise_id="9432">
    <datapoint name="BidCos-RF.OEQ0801918:2.TEMPERATURE" type="TEMPERATURE" ise_id="9434" value="13.300000" valuetype="4" valueunit="°C" timestamp="1572028647"/>
    <datapoint name="BidCos-RF.OEQ0801918:2.LOWBAT" type="LOWBAT" ise_id="9433" value="false" valuetype="2" valueunit="" timestamp="1572028647"/>
    </channel>
    <channel name="HM-WDS30-OT2-SM-2 OEQ0801918:3" ise_id="9435">
    <datapoint name="BidCos-RF.OEQ0801918:3.TEMPERATURE" type="TEMPERATURE" ise_id="9437" value="-2.800000" valuetype="4" valueunit="°C" timestamp="1572028647"/>
    <datapoint name="BidCos-RF.OEQ0801918:3.LOWBAT" type="LOWBAT" ise_id="9436" value="false" valuetype="2" valueunit="" timestamp="1572028647"/>
    </channel>
    <channel name="HM-WDS30-OT2-SM-2 OEQ0801918:4" ise_id="9438">
    <datapoint name="BidCos-RF.OEQ0801918:4.TEMPERATURE" type="TEMPERATURE" ise_id="9440" value="2.800000" valuetype="4" valueunit="°C" timestamp="1572028647"/>
    <datapoint name="BidCos-RF.OEQ0801918:4.LOWBAT" type="LOWBAT" ise_id="9439" value="false" valuetype="2" valueunit="" timestamp="1572028647"/>
    </channel>
    <channel name="Pool Temperaturen:5" ise_id="9441">
    <datapoint name="BidCos-RF.OEQ0801918:5.TEMPERATURE" type="TEMPERATURE" ise_id="9443" value="0.000000" valuetype="4" valueunit="°C" timestamp="0"/>
    <datapoint name="BidCos-RF.OEQ0801918:5.LOWBAT" type="LOWBAT" ise_id="9442" value="false" valuetype="2" valueunit="" timestamp="1572028647"/>
    </channel>
    </device>
    </state>
    In der Abfrage habe ich die ID 9432 angegeben, dazu möchte ich erst mal den Namen rausfiltern, später dann auch den "type=" und natürlich "value="

    Das ganze bekomme ich schon mit grep, sid und cut hin, jedoch denke ich gibt es bestimmt noch eine bessere Möglichkeit. Als Scriptsprache wird bash verwendet.
    Der Ansatz mit "xmlstarlet" ist auch nicht schlecht, jedoch bekomme ich nicht genau den Bereich gefiltert den ich benötige.


    Hat jemand eine Idee wie das am besten zum umsetzten wäre?
    Gruß DR.Chris
    ka.homelinux.org

  8. #8
    Registrierter Benutzer
    Registriert seit
    Apr 2009
    Ort
    Erde
    Beiträge
    2.814
    XPath macht da am meisten Sinn, es dürft auch mit CSS Selektoren gehen, ich bleibe aber xpath, libxml2 ist da ziemlich performant...

    [edit]ist halt xml, also soltlte man auch entsprechende Mittel verwenden, schon allein um das escaping los zu werden...
    Geändert von nopes (30.10.19 um 19:48 Uhr)
    Gruß nopes
    (,,,)---(^.^)---(,,,) /var/log/messages | grep cat

  9. #9
    Registrierter Benutzer
    Registriert seit
    May 2018
    Beiträge
    145
    Code:
    grep -Poe '(?<=channel name=").*?(?=")'
    Funktioniert zumindest bei den paar Zeilen die Du als Beispiel gepostet hast. Dafür gibt es aber wie schon gesagt besser geeignete Programme wie z. B. xgrep, sgrep, xmllint (xpath), XML::Twig, ..

  10. #10
    @SlopePointNZ Avatar von craano
    Registriert seit
    Jul 2004
    Beiträge
    1.313
    Code:
    xmlstarlet sel -t -m "/state/device/channel[@ise_id=\"9429\"]" -v @name file.txt
    xmlstarlet sel -t -m "/state/device/channel[@ise_id=\"9429\"]/datapoint" -v  @type file.txt
    Wenn Du die XML Daten per wget oder curl oder wie auch immer ranholst, kannst Du natürlich auch eine Pipe verwenden
    Code:
    ~$ cat file.txt | xmlstarlet sel -t -m "/state/device/channel[@ise_id=\"9429\"]/datapoint" -v  @type && echo ""
    TEMPERATURELOWBAT
    Geändert von craano (31.10.19 um 11:03 Uhr)

Ähnliche Themen

  1. Asus P2520 - Cursor springt allein an andere Textstelle
    Von OUTBREAK im Forum Anwendungen Allgemein, Software
    Antworten: 4
    Letzter Beitrag: 06.03.16, 12:19

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •