Ergebnis 1 bis 6 von 6
  1. #1
    Erdapfel
    Themenstarter

    Registriert
    08.2011
    Beiträge
    4

    Abschnitte aus Text löschen mit sed

    Moin moin!

    folgendes:
    Habe aus Safari's History.plist folgenden Abschnitt:
    Code:
        <dict>           
     <key></key>
                <string>http://www.macuser.de/forum/f30/safari-alle-cache-544226/</string>
                <key>D</key>
                <array>
                    <integer>1</integer>
                </array>
                <key>lastVisitedDate</key>
                <string>335083562.5</string>
                <key>title</key>
                <string>Safari: Alle Cache Dateien via Script löschen</string>
                <key>visitCount</key>
                <integer>1</integer>
            </dict>
    In der kompletten Datei sind natürlich noch mehr solche Abschnitte, die alle den selben Aufbau haben.

    Ich möchte jetzt per Script komplette Abschnitte löschen, in denen bestimmte Keywords vorkommen. Hier als Beispiel macuser.de
    Nach einiger Suche bin ich auf den Befehl sed gekommen und habe nun vor, alles, was zwischen
    Code:
        <dict>            <key></key>
                <string>http://www.macuser.de/
    und dem darauffolgenden </dict> kommt, zu löschen.

    Zuerst habe ich also die History.plist woanders hinkopiert, und mit
    Code:
    plutil -convert xml1
    so umgewandelt, dass ich sie mit vi lesen kann.

    Anschließend soll mit folgendem Befehl der entsprechende Bereich gelöscht werden, was allerdings nicht funktioniert:
    Code:
    sed 's!<dict><key><\/key><string>http:\/\/www.macuser.de\/*<\/dict>!!g' History.plist >HistoryNeu.plist
    Ich bekomme keine Fehlermeldung, der Inhalt der alten Datei wird in HistoryNeu.plist ausgegeben, aber der entsprechende Bereich ist immernoch vorhanden.

    Liegt das daran, dass mein Suchstring über mehrere Zeilen verteilt ist? Muss ich außer den / sonst noch was escapen? Funktioniert der * als Platzhalter nicht? Oder gibt's viel einfachere oder schlankere Lösungen?

    Sinn und Unsinn der Aktion lassen wir mal außen vor, dient auch zum Großteil zu Übungszwecken

    Vielleicht hat ja jemand eine Idee.

    Schöne Grüße!
    Max

  2. #2
    Charlamowsky Avatar von Rastafari
    Registriert
    03.2005
    Beiträge
    12.944
    1) Der Stern ist kein Platzhalter, sondern eine beliebige Wiederholung des vorangegangenen Zeichens (Null mal oder öfter.)
    Der Platzhalter für jedes Zeichen ist der Punkt. Das Muster für eine beliebige Zeichenfolge ist also:
    Code:
    .*
    2) sed sucht/erkennt natürlich auch Whitespace. Du hast schlicht und ergreifend keinen Treffer zu erwarten wenn du den nicht vorher entfernst.

    3) Den Schrägstrich escapen? Warum das denn? Den Backslash, ja. Den Slash? Nein.

  3. #3
    Erdapfel
    Themenstarter

    Registriert
    08.2011
    Beiträge
    4
    zu 1)
    Danke, dann mach ich also den Punkt noch davor.

    zu 2)
    Es gibt auch nicht zufällig 'ne Möglichkeit, Whitespace bei der Suche zu "überspringen", oder?

    zu 3)
    Auf die Idee kam ich, weil zum Trennen von Suchbegriff und Ersatzwort ja ein / benutzt wird, der leider auch in meinem Suchbegriff vorkommt. Ohne den / zu escapen kam es zu Fehlermeldungen.

  4. #4
    Charlamowsky Avatar von Rastafari
    Registriert
    03.2005
    Beiträge
    12.944
    Zitat Zitat von LazyJoe Beitrag anzeigen
    Es gibt auch nicht zufällig 'ne Möglichkeit, Whitespace bei der Suche zu "überspringen"
    Nimm ihn ins Suchmuster auf. zB:
    Code:
    s,\(</[^>]*>\)[ T]*\(<[^/>]*>\),\1\2,g
    Das rote T steht hier (damit mans sieht...) für einen Tab.
    Dieser Subst entfernt alle Folgen von Leerzeichen und/oder Tabs zwischen normal schliessenden und öffnenden Tags.
    (Berücksichtigt aber noch immer keine Newlines. "sed" ist zum zeilenweisen arbeiten gut, für Absatz- oder Blockbasierten Text... Phhuh!)
    Zum besseren Verständnis hier noch ein paar mal die gleiche Zeile mit "Syntax Highlights für Arme". Jeweils zusammengehöriges, das ein Strukturelement bildet, ist hervorgehoben:
    Code:
    s,\(</[^>]*>\)[ T]*\(<[^/>]*>\),\1\2,g
    
    s,\(</[^>]*>\)[ T]*\(<[^/>]*>\),\1\2,g
    
    s,\(</[^>]*>\)[ T]*\(<[^/>]*>\),\1\2,g
    
    s,\(</[^>]*>\)[ T]*\(<[^/>]*>\),\1\2,g
    weil zum Trennen von Suchbegriff und Ersatzwort ja ein / benutzt wird
    Nein. Du hast dafür das ! definiert. Das erste Zeichen nach dem Befehl s gilt, und du kannst dir (fast) alles aussuchen was im Muster ansonsten nicht vorkommt. Jeder Ausdruck kann sein eigenes Trennzeichen verwenden, wie es grade gut passt. Wie du oben siehst, finde ich das Komma sehr praktisch und viel besser lesbar.
    Hier noch mal die gleiche Zeile mit beliebigen anders definierten Trennern (ist alles das gleiche):
    Code:
    s_\(</[^>]*>\)[ T]*\(<[^/>]*>\)_\1\2_g
    
    sG\(</[^>]*>\)[ T]*\(<[^/>]*>\)G\1\2Gg
    
    s-\(</[^>]*>\)[ T]*\(<[^/>]*>\)-\1\2-g
    Geändert von Rastafari (15.08.2011 um 13:40 Uhr)

  5. #5
    Granny Smith
    Registriert
    08.2010
    Beiträge
    13
    Hallo.

    Mit Perl lässt sich das lösen.
    Der Ersetzungsoperator von Perl funktioniert auch über Zeilenumbrüche hinweg, so dass man auch ganze Blöcke bearbeiten kann.

    Beispiel

    testfile:

    Code:
    Hier steht was
    und noch was
        <dict>           
     <key></key>
                <string>http://www.macuser.de/forum/f30/safari-alle-cache-544226/</string>
                <key>D</key>
                <array>
                    <integer>1</integer>
                </array>
                <key>lastVisitedDate</key>
                <string>335083562.5</string>
                <key>title</key>
                <string>Safari: Alle Cache Dateien via Script löschen</string>
                <key>visitCount</key>
                <integer>1</integer>
    </dict> Test 
    Ende
    Hier der Perl EInzeiler:
    Code:
    cat testfile | perl -e '@a = <STDIN> ; $s = "@a" ; $s =~ s#<dict>.*<key></key>.*<string>http://www.macuser.de.*</dict>##gs ; print $s'
    und das Ergebnis:
    Code:
    Hier steht was 
    und noch was
          Test 
     Ende
    Geht evtl. auch eleganter aber scheint zu funktionieren
    Vielleicht hilft das ja weiter.

    Gruß,
    René

  6. #6
    Erdapfel
    Themenstarter

    Registriert
    08.2011
    Beiträge
    4
    Oh, das klingt deutlich komplizierter als angenommen.
    Muss mich jetzt leider bis zum Ende der Woche in die Internet-freie Zone verabschieden, aber danke euch beiden schonmal für die Erklärungen bzw. das Perl-Script!

    Denke mal ich werde das dann mit Perl lösen!

Berechtigungen

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