sed mit kaufmännischem Und (&) verwenden

19

Ich verwende sed, um Muster in SAS-Dateien zu suchen und zu ersetzen, anstatt sie einzeln zu ändern. Das Problem ist, dass ich versuche, Makrovariablen zu ersetzen, und wenn ich das kaufmännische Und verwende, wird es nicht richtig verarbeitet.

Here's my code:
sed -ie 's/user=&uid./user=&sysuserid./g' *_table_*.sas

Wenn ich diesen Befehl ausführe, scheint er alle Arten von Funky Stuff mit dem Originaltext anzufügen und auszuführen.

Frage: Wie ersetze ich Text, der kaufmännisches Und enthält, durch den Befehl sed?

lucasdavis500
quelle
6
&ist ein Sonderzeichen , so dass es entgangen , wenn sie in der RHS verwendet werden muss - in Ihrem Fall müssen Sie laufen , 's/user=&uid./user=\&sysuserid./g'obwohl ich Sie auch brauchen , um die Flucht der Punkt in der LHS vermuten eine wörtliche Punkt zu entsprechen , so dass Sie wirklich brauchen's/user=&uid\./user=\&sysuserid./g'
don_crissti
1
ja, '&' auf der rechten Seite bedeutet im Grunde "alles, was auf der linken Seite übereinstimmt". Verlassen Sie es also mit '\'. Sie sollten das als Antwort geben und nicht nur als Kommentar.
Edward Falk
Ich musste nicht die erste Periode entkommen ... nur ein Kopf hoch in jemand anderes war neugierig :)
Lucasdavis500

Antworten:

25

&im Ersetzungstext ist das Besondere: es bedeutet , „den ganzen Teil der Eingabe , die durch das Muster abgestimmt wurde“, so , was Sie hier tun , ersetzt user=&uidXmit user=user=&uidXsysuserid.. Verwenden Sie, um ein kaufmännisches Und in den Ersetzungstext einzufügen \&.

Eine andere Sache, die falsch aussieht, ist, dass .das Suchmuster für ein beliebiges Zeichen steht (außer für eine neue Zeile), aber das .am Ende des Ersetzungstextes ist ein wörtlicher Punkt. Wenn Sie nur die Literalzeichenfolge ersetzen möchten user=&uid., schützen Sie die .mit einem Backslash.

sed -e 's/user=&uid\./user=\&sysuserid./g'

Wenn Sie ein beliebiges Zeichen ersetzen und es im Ergebnis beibehalten möchten, fügen Sie das Zeichen in eine Gruppe ein und verwenden Sie \1in der Ersetzung, um auf diese Gruppe zu verweisen.

sed -e 's/user=&uid\(.\)/user=\&sysuserid\1/g'

In Anbetracht der Wiederholung zwischen dem Originaltext und der Ersetzung sollten Sie trotzdem Gruppen verwenden:

sed -e 's/\(user=&\)u\(id\.\)/\1sysuser\2/g'

dh "ersetzen udurch sysuserzwischen user=&und id.".

Gilles 'SO - hör auf böse zu sein'
quelle
Kannst du Gruppen erklären?
Lucasdavis500
2
@ lucasdavis500 Eine Gruppe identifiziert einen Teil des Musters. Es wird durch Backslash-Klammern begrenzt. Ein Beispiel \(user=&\)ist ein Muster, user&das mit der Übereinstimmungszeichenfolge übereinstimmt und diese als Gruppe speichert (Gruppennummer 1, da dies die erste Gruppe im Muster ist). Dann wird in der Ersetzung \1durch die für Gruppe 1 gespeicherte Zeichenfolge ersetzt.
Gilles 'SO - hör auf, böse zu sein'
meinst du (user = &) speichert user = &, nicht user &?
Lucasdavis500
@ lucasdavis500 Ich verstehe deinen Kommentar nicht. Das Zeichen =in regulären Ausdrücken und im Ersetzungstext steht für sich selbst, user=&stimmt also nur überein user=&, und user=&im Ersetzungstext ergibt sich, user=gefolgt von dem Teil der Zeile, auf den der reguläre Ausdruck zutrifft.
Gilles 'SO - hör auf böse zu sein'
1
@ lucasdavis500 Das =Zeichen hat keine besondere Bedeutung. user=&Im Ersetzungstext wird user=gefolgt vom originalen übereinstimmenden Text erzeugt. user=\&im ersatztext ergibt sichuser=&
Gilles 'SO- hör auf böse zu sein'