Ich plane, bestimmte Zeichenfolgen in einer Datei zu ersetzen. Daher verwende ich sed.
Ich möchte, dass der String ersetzt wird, während sed stattdessen den String liest und den Text in der Mitte des Strings anhängt.
Beispiel:
string in myfile : user=blabla
string that I want to obtain: user=bob
also führe ich sed auf diese Weise aus, damit es nach der Zeichenfolge "user=" sucht und diese durch "user=bob" ersetzt.
sed -i 's/user=*/user=bob/' myfile
Was ich bekomme ist
user=bobblabla
Im Grunde denkt sed, dass ich nur diesen Teil ersetzen möchte, während ich die ganze Zeichenfolge durch die neue Zeichenfolge ersetzen möchte. Ich dachte, dass das * sed anweisen würde, alles zu berücksichtigen, was danach kommt, aber das funktioniert nicht.
Da ich nicht weiß, was das „blabla“ sein wird, kann ich es nicht in den sed-Befehl einfügen. Wie weise ich sed an, eine Zeichenfolge zu suchen, die mit „user=“ beginnt, und die gesamte Zeichenfolge durch die neue zu ersetzen?
Antwort1
Sie scheinen Shell-Muster mit regulären Ausdrücken zu verwechseln. In einem Shell-Muster *
bedeutet null oder mehr beliebige Zeichen. In einem regulären Ausdruck, der sed
in seinen Mustern erwartet wird, *
bedeutet null oder mehr des vorherigen Atoms. In Ihrem Beispiel ist dieses Atom das . Es wird =
also nach gesucht, gefolgt von null oder mehr, und die übereinstimmende Zeichenfolge wird durch ersetzt . Das gewünschte Muster ist , gefolgt von einem beliebigen Zeichen ( ) null oder mehr Mal, sodass Ihr Befehl lautet:sed
user
=
user=bob
user=.*
user=
.
sed
sed -i 's/user=.*/user=bob/' myfile
Antwort2
Wie GaryJohn sagte, haben Sie den regulären Ausdruck falsch verwendet. (* -> .*)
Aber wenn Sie schon dabei sind, würde ich noch einen Schritt weiter gehen ... Ich weiß nicht, wie Ihre Datei tatsächlich aussieht, aber nur aus Übungsgründen würde ich versuchen, Ihren Such-/Ersetzungsvorgang etwas sicherer zu machen.
Angenommen, Sie möchten das Ding über eine Datei wie diese ausführen:
user=john
superuser=jimmy # don't want to change this line!
user=L33t_us3rn4m3 # that should work too, and these comments should remain intact as well, btw
# in the line below, I want to change user=hello to user=bob
# but in the comments, "user=hello" should remain intact
user=hello
Mit Ihrer aktuellen sed-Syntax würde das ziemlich schiefgehen. Um es etwas spezifischer zu machen, könnten Sie Folgendes versuchen:
sed -i 's/^user=[A-Za-z0-9_]*/user=bob/g' /tmp/myfile
Dieser Wille:
- wird nur ausgelöst, wenn die Zeile tatsächlich mit „Benutzer“ beginnt (das ^)
- Ändern Sie "user=" nur, wenn es aus 0 oder mehr Buchstaben, Ziffern oder Unterstrichen besteht
- alles hinter dem Benutzernamen (also die Kommentare in meinem Beispiel) unverändert lassen
Dies ist keineswegs eine supersichere Sache, die immer und überall funktioniert, wo Sie Benutzer umbenennen möchten. Das hängt natürlich davon ab, wie Ihre Konfigurationsdatei eingerichtet ist und was Sie erwarten würden. Aber meine Antwort soll ein wenig „Denkanstoß“ geben, denn angesichts einer (Anzahl von) Konfigurationsdateien, die groß genug sind, um so viele Benutzernamen zu erwarten, dass man dies nicht manuell tun möchte, scheint das blinde Ersetzen von „user=.*“ möglicherweise gefährlich. Vielleicht möchten Sie etwas Zeit damit verbringen, diese Art von Operationen zu verfeinern :)
Viel Glück.