Frage an sed – sed: Ersetzen Sie einen Teil einer Linie

34

Wie kann man einen Teil einer Linie durch sed ersetzen?

Die Linie

DBSERVERNAME     xxx

sollte ersetzt werden durch:

DBSERVERNAME     yyy

Der Wert xxx kann variieren, und zwischen dbservername und dem Wert befinden sich zwei Registerkarten. Dieses Name-Wert-Paar ist eines von vielen aus einer Konfigurationsdatei.

Ich habe es mit folgendem Rückverweis versucht:

echo "DBSERVERNAME    xxx" | sed -rne 's/\(dbservername\)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'

und das führte zu einem Fehler: Ungültiger Verweis \ 1 auf die RHS des Befehls `s '.

Was stimmt nicht mit dem Ausdruck? Verwendung von GNU sed.

Deine Antwort

7   die antwort
1

Das könnte für Sie funktionieren:

echo "DBSERVERNAME     xxx" | sed 's/\S*$/yyy/'
DBSERVERNAME     yyy
1

sollten Sie den Dingen nicht entkommen. dh

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/\1 yyy/gip'
1

Sie sollten Ihren Eltern nicht entkommen. Versuchen:

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/\1 yyy/gip'
0

sed -re 's/DBSERVERNAME[ \t]*([^\S]+)/\yyy/ig' temp.txt

oder dieses

awk '{if($1=="DBSERVERNAME") $2 ="YYY"} {print $0;}' temp.txt

2

dass Sie das nicht tun müssen. Versuchen:

sed -rne 's/(dbservername)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'
8

aber warum brauchen Sie überhaupt einen Rückverweis, wenn der erste Teil der Zeile konstant ist?

Sie könnten es einfach tun

sed -e 's/dbservername.*$/dbservername yyy/g'
Dies ist meine Stimme, weil es die einfachste Lösung für ein einfaches Problem ist. Durch die Verwendung eines Rückverweises können Sie die beiden Kopien von nicht falsch eingebendbservername. Es ist hier offensichtlich, aber wenn ich postgresql.conf in sed ändere, ist es schwer auf einen Blick zu erkennen, ob ich getippt habelisten_address oderlisten_addresses (postgresql.conf). Beide sehen plausibel aus, aber nur einer ist richtig. Iain Samuel McLean Elder
Guter Punkt! Ich hatte gerade gelernt, wie man reguläre Ausdrücke + sed verwendet, und der Verstand entschied sich gerade für reguläre Ausdrücke, als ich diese bestimmte Aufgabe sah. calvinkrishy
42

Das funktioniert:

sed -rne 's/(dbservername)\s+\w+/\1 yyy/gip'

(Wenn Sie die Option -r verwenden, müssen Sie den Parens nicht entkommen.)

Ein bisschen Erklärung:

-r ist erweiterte reguläre Ausdrücke - macht einen Unterschied, wie der reguläre Ausdruck geschrieben wird.-n druckt nicht, wenn nicht anders angegeben -sed druckt standardmäßig anders,-e bedeutet, was folgt, ist ein Ausdruck. Lassen Sie uns den Ausdruck aufschlüsseln:s/// ist der Befehl zum Suchen und Ersetzen, und was zwischen dem ersten Paar ist, ist der zu vergleichende reguläre Ausdruck und dem zweiten Paar der Ersatz.gip, der auf den Befehl search replace folgt;g bedeutet global, d. h. jede Übereinstimmung anstelle nur der ersten wird in einer Zeile ersetzt;i ist die Unterscheidung zwischen Groß- und Kleinschreibung;p bedeutet Drucken, wenn Sie fertig sind (merken Sie sich das-n Flagge von früher!),Die Klammern stellen einen Match-Part dar, der später angezeigt wird. Sodbservername ist das erste Spielteil,\s ist whitespace,+ bedeutet eine oder mehrere (vs*, null oder mehr) Vorkommen,\w ist ein Wort, das ein Buchstabe, eine Ziffer oder ein Unterstrich ist,\1 ist ein spezieller Ausdruck für GNUsed Damit wird die erste Übereinstimmung in Klammern in der zugehörigen Suche gedruckt.
Ich weiß, ihr habt viel Erfahrung mit Shell-Befehlen ... aber bitte kümmert euch, wo immer möglich, um die aufstrebenden Linux-Noobs ... alles drin'' muss erklärt werden .... oder ich muss das ganze durchgehendoc Mahesha999

Verwandte Fragen