IT-MÜCKE

sed: Teile von Mustern ersetzen

Beitragsdatum 19.11.2016
Letzte Aktualisierung 22.11.2016
Betrifft Linux allgemein, sed

Einleitung

Ich wollte kürzlich in einem meiner Dokuwikis zahlreiche Seiten und Namensräume umbenennen. Es gibt für die Umbenennung einer Seite/eines Namensraumes ein Plugin: move.

Dieses Plugin kümmert sich dann auch gleich um die sogenannten Backlinks auf die umzubenennende Seite, verschiebt Seiten über Namensräume hinweg und ist sehr praktisch - so lange man nicht eine große Anzahl von Seiten/Namespaces verschieben möchte.

Da Dokuwiki auf Dateisystemebene Seiten speichert (in einfachen Textfiles) kann man für solche größeren Aufgaben Standard-Linux-Tools verwenden.

Für das Verschieben von Seiten benutzt man entsprechend mv. Anschließend müssen aber die Backlinks auf die verschobenen Seiten angepasst werden. Dafür bietet sich sed an.


Aufgabe

Es sollten diverse Muster gesucht und nur Teile davon ersetzt bzw. neue Teile innerhalb des Musters eingefügt werden.

Beispiel:

# Ist-Zustand:
Ein Link im Dokuwiki: [[namespace:site1|Linktext]]

# Soll-Zustand: statt site1 soll site001 eingetragen sein
Ein Link im Dokuwiki: [[namespace:site001|Linktext]]

Lösung

  • sed kann mit Variablen arbeiten
  • Das Suchmuster wird in Teile gespalten, die in Variablen gespeichert werden
  • Das Ersetzungmuster setzt sich aus den Variablen zusammen und dem neuen Text, der eingefügt werden soll
  • Im Beispiel:
    • Suchmuster Teil 1: [[namespace:site → wird zu Variable1
    • Suchmuster Teil 2: [0-9] → wird zu Variable2
    • Ersetzungsmuster: Variable1 + 00 + Variable2 (die „ + “ dienen nur zur Verdeutlichung,kurz geschrieben sollte das so aussehen: „Variable100Variable2“)
  • In sed werden Variablen im Muster durch Einschließen in Klammern „(“ und „)“ definiert. Die Klammern müssen escaped werden: \( und \)
  • Auf die Variablen kann bei der Ersetzung mittels \1, \2 usw. referenziert werden
  • Beispiel in sed:
    sed 's/\(\[\[namespace:site\)\([0-9]\{1\}\)/\100\2/g'
    
    # Suchmuster: "[[namespace:site" (Variable1) und [0-9] (Variable2)
    # Ersetzung: "[[namespace:site"00 und die Zahl, die oben gefunden wurde, also: Variable100Variable2

Test:

# Inhalt Textdatei: test.txt
Test [[namespace:site1|Link]] Testtest [[namespace:site2|Link]]

# sed:
sed 's/\(\[\[namespace:site\)\([0-9]\{1\}\)/\100\2/g' test.txt 

# Ausgabe:
Test [[namespace:site001|Link]] Testtest [[namespace:site002|Link]]

Das mag kompliziert aussehen, ist aber sehr praktisch, um viele Dateien zu bearbeiten.


Quellen:


Ähnliche Themen im blog:
sed


zurück