Angenommen, ich habe eine 'abbc'-Zeichenfolge und möchte Folgendes ersetzen:
- ab -> bc
- bc -> ab
Wenn ich zwei Ersetzungen versuche, ist das Ergebnis nicht das, was ich will:
echo 'abbc' | sed 's/ab/bc/g;s/bc/ab/g'
abab
Welchen sed-Befehl kann ich also wie unten beschrieben ersetzen?
echo abbc | sed SED_COMMAND
bcab
BEARBEITEN : Eigentlich könnte der Text mehr als 2 Muster haben und ich weiß nicht, wie viele Ersetzungen ich benötigen werde. Da es eine Antwort gab, die besagt, dass sed
es sich um einen Stream-Editor handelt und seine Ersetzungen gierig sind, denke ich, dass ich dafür eine Skriptsprache verwenden muss.
g
Flag von diesen beidens///
Befehlen fallen und das wird funktionieren.ab
oderbc
in der ursprünglichen Eingabe.Antworten:
Vielleicht so etwas:
Ersetzen Sie
~
durch ein Zeichen, von dem Sie wissen, dass es nicht in der Zeichenfolge enthalten ist.quelle
\x0
für verwenden können~~
.g
notwendig und was macht es?g
ist global - ersetzt alle Instanzen des Musters in jeder Zeile anstelle der ersten (dies ist das Standardverhalten).Ich benutze immer mehrere Anweisungen mit "-e"
$ sed -e 's:AND:\n&:g' -e 's:GROUP BY:\n&:g' -e 's:UNION:\n&:g' -e 's:FROM:\n&:g' file > readable.sql
Dies wird ein '\ n' vor allen ANDs, GROUP BYs, UNIONs und FROMs anhängen, während '&' die übereinstimmende Zeichenfolge bedeutet und '\ n &' bedeutet, dass Sie die übereinstimmende Zeichenfolge durch ein '\ n' vor dem 'übereinstimmenden' ersetzen möchten '
quelle
Hier ist eine Variation der Antwort von ooga , die für mehrere Such- und Ersetzungspaare funktioniert, ohne prüfen zu müssen, wie Werte wiederverwendet werden können:
Hier ist ein Beispiel:
Vor:
nach dem:
Beachten Sie, dass
\b
Wortgrenzen bezeichnet werden, was das verhindert________
Suche gestört wird (ich verwende GNU sed 4.2.2 unter Ubuntu). Wenn Sie keine Wortgrenzensuche verwenden, funktioniert diese Technik möglicherweise nicht.Beachten Sie auch, dass dies die gleichen Ergebnisse liefert wie das Entfernen des
s/________//g
und Anhängen&& sed -i 's/________//g' path_to_your_files/*.txt
des Befehls an das Ende des Befehls, jedoch keine zweimalige Angabe des Pfads erforderlich macht.Eine allgemeine Variante wäre die Verwendung
\x0
oder_\x0_
anstelle von,________
wenn Sie wissen, dass in Ihren Dateien keine Nullen angezeigt werden, wie von jthill vorgeschlagen .quelle
sed 's/ab/xy/' | sed 's/cd/ab/' .....
)sed
ist ein Stream-Editor. Es sucht und ersetzt gierig. Die einzige Möglichkeit, das zu tun, wonach Sie gefragt haben, besteht darin, ein Zwischensubstitutionsmuster zu verwenden und es am Ende wieder zu ändern.echo 'abcd' | sed -e 's/ab/xy/;s/cd/ab/;s/xy/cd/'
quelle
Dies könnte für Sie funktionieren (GNU sed):
Dies verwendet eine Nachschlagetabelle, die vorbereitet und im Haltebereich (HS) gehalten und dann an jede Zeile angehängt wird. Ein eindeutiger Marker (in diesem Fall
\n
) wird dem Zeilenanfang vorangestellt und als Methode verwendet, um die Suche über die gesamte Länge der Zeile zu verfolgen. Sobald der Marker das Ende der Zeile erreicht hat, ist der Vorgang abgeschlossen und die Nachschlagetabelle und die verworfenen Marker werden ausgedruckt.NB Die Nachschlagetabelle wird gleich zu Beginn vorbereitet und ein zweiter eindeutiger Marker (in diesem Fall
:
) ausgewählt, um nicht mit den Ersetzungszeichenfolgen in Konflikt zu geraten .Mit einigen Kommentaren:
Die Tabelle funktioniert folgendermaßen:
quelle
Möglicherweise ist dies ein einfacherer Ansatz für das Auftreten einzelner Muster, den Sie wie folgt versuchen können: echo 'abbc' | sed 's / ab / bc /; s / bc / ab / 2'
Meine Ausgabe:
Für mehrere Mustervorkommen:
Beispiel
Hoffe das hilft !!
quelle
Tcl hat einen eingebauten für diese
Dies funktioniert, indem Sie die Zeichenfolge zeichenweise durchlaufen und Zeichenfolgenvergleiche ab der aktuellen Position durchführen.
In Perl:
quelle
Hier basiert ein
awk
auf Oogas basierendessed
quelle