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:
2) sed sucht/erkennt natürlich auch Whitespace. Du hast schlicht und ergreifend keinen Treffer zu erwarten wenn du den nicht vorher entfernst.Code:.*
3) Den Schrägstrich escapen? Warum das denn? Den Backslash, ja. Den Slash? Nein.
Ergebnis 1 bis 6 von 6
- 15.08.2011, 12:15 #1Erdapfel
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:
In der kompletten Datei sind natürlich noch mehr solche Abschnitte, die alle den selben Aufbau haben.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>
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
und dem darauffolgenden </dict> kommt, zu löschen.Code:<dict> <key></key> <string>http://www.macuser.de/
Zuerst habe ich also die History.plist woanders hinkopiert, und mitso umgewandelt, dass ich sie mit vi lesen kann.Code:plutil -convert xml1
Anschließend soll mit folgendem Befehl der entsprechende Bereich gelöscht werden, was allerdings nicht funktioniert:
Ich bekomme keine Fehlermeldung, der Inhalt der alten Datei wird in HistoryNeu.plist ausgegeben, aber der entsprechende Bereich ist immernoch vorhanden.Code:sed 's!<dict><key><\/key><string>http:\/\/www.macuser.de\/*<\/dict>!!g' History.plist >HistoryNeu.plist
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
- 15.08.2011, 12:57 #2
- 15.08.2011, 13:03 #3Erdapfel
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.
- 15.08.2011, 13:29 #4
Nimm ihn ins Suchmuster auf. zB:
Das rote T steht hier (damit mans sieht...) für einen Tab.Code:s,\(</[^>]*>\)[ T]*\(<[^/>]*>\),\1\2,g
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
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.weil zum Trennen von Suchbegriff und Ersatzwort ja ein / benutzt wird
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)
- 15.08.2011, 14:10 #5Granny 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:
Hier der Perl EInzeiler: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
und das Ergebnis:Code:cat testfile | perl -e '@a = <STDIN> ; $s = "@a" ; $s =~ s#<dict>.*<key></key>.*<string>http://www.macuser.de.*</dict>##gs ; print $s'
Geht evtl. auch eleganter aber scheint zu funktionierenCode:Hier steht was und noch was Test Ende
Vielleicht hilft das ja weiter.
Gruß,
René
- 15.08.2011, 18:40 #6Erdapfel
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!


Zitieren

