2013-07-18 17 views
5

Ich habe einen Textkörper, der Gruppen enthält, die mit <>, ## oder || abgegrenzt sind. Die Blöcke nie überlappen, können jedoch mehrere Linien kreuzen, etwa so:Ersetzen mehrere begrenzte Blöcke in sed

#A fully emphasized line# 
A line with #emphasis inside#. 
#Several lines of 
text 
With emphasis# 
no emphasis 
Line #with# multiple #emphasis#. 
Line <with some > |text of| #each type#. 

Ich versuche, jedes Paar von Begrenzungszeichen zu ersetzen mit [und] und den Endbegrenzer nach dem] setzen; zum Beispiel sollte die letzte Zeile sein:

Line [with some ]> [text of]| [each type]#. 

Ich habe einen sed-Skript gebildet, die den ersten Teil tun:

sed -e ':left s/[#|<]/[/; t right; n; b left :right s/[#|>]/]/; t left;n; b right' 

Aber wenn ich versuche & zu verwenden (oder (..) + \ 1), um den Charakter zurück in wie folgt zu setzen:

sed -e ':left s/[#|<]/[/; t right; n; b left :right s/[#|>]/]&/; t left;n; b right' 

ich folgendes:

[A fully emphasized line][ 
A line with ][emphasis inside][. 
][Several lines of 
text 
With emphasis][ 
no emphasis 
Line ][with][ multiple ][emphasis][. 
Line [with some ]]]]]]> [text of[ [each type[. 

Ich bin mir nicht sicher, was hier schief gegangen ist - es scheint irgendwie mit dem Musterblock zu verschrauben. Ich könnte es durch drei Anrufe ersetzen (hardcoded one pro Spieltyp), aber das scheint übermäßig.

Antwort

4

Versuchen Sie folgenden Befehl. Er liest die gesamte Datei in den Speicher und tun globale Ersetzungen für jedes Paar von Begrenzungszeichen:

sed -e ' 
    :a 
    $! { N; ba }; 
    s/#\([^#]*\)#/[\1]#/g; 
    s/<\([^>]*\)>/[\1]>/g; 
    s/|\([^|]*\)|/[\1]|/g 
' infile 

Es ergibt:

[A fully emphasized line]# 
A line with [emphasis inside]#. 
[Several lines of 
text 
With emphasis]# 
no emphasis 
Line [with]# multiple [emphasis]#. 
Line [with some ]> [text of]| [each type]#. 
+1

kühlen. Die zusammengeführte Version funktioniert auch damit, also können die drei Suchen durch ersetzt werden: 's/[# | <]\([^#|>] * \) \ ([# |>] \)/[\ 1] \ 2/g; ' –

+0

user2596375 - Die drei sed-Ausdrücke sind besser, weil Ihr Muster ein beliebiges Paar Trennzeichen ersetzt, nicht unbedingt übereinstimmende. '#text>' zum Beispiel wird durch '[text]>' ersetzt, obwohl es nicht '# text #' ist. – gbrener