Ersetzen Sie den Inhalt der Regex-Erfassungsgruppe durch sed


16

Ich versuche, meine Datei nginx.conf programmgesteuert zu bearbeiten, die eine Zeile wie die folgende enthält:

        access_log /var/log/nginx/access.log;

was ich so sehen will:

        access_log /dev/stdout;

Ich glaube, der Regex ^\s*access_log([^;]*);erfasst den /var/log/nginx/access.logTeil in einer Erfassungsgruppe, aber ich bin nicht sicher, wie ich die Erfassungsgruppe richtig durch sed ersetzen soll.

ich habe es versucht

echo "        access_log /var/log/nginx/access.log;" | sed 's/^\s*access_log([^;]*);/\1\\\/dev\\\/stdout/'

aber ich erhalte den Fehler:

sed: -e expression #1, char 45: invalid reference \1 on `s' command's RHS

wenn ich es versuche sed -rdann liegt kein fehler vor, aber die ausgabe ist nicht das was ich erwarte:

 /var/log/nginx/access.log\/dev\/stdout

Ich versuche, mit der Erfassungsgruppe und so weiter schlau zu sein und nicht direkt nach "access_log /var/log/nginx/access.log;" zu suchen. Falls die Verteilung den Standardspeicherort der Protokolldatei ändert.


1
sed '/access_log/s|/[^;]\+|/dev/stdout|'
— Costas

@Costas Wenn du das beantworten würdest, würde ich dich unterstützen, da das auch funktioniert!
— Abe Voelker

Antworten:


16

Ein paar Fehler da.

Erstens, da sedAnwendungen grundlegende reguläre Ausdrücke, müssen Sie \(und \)eine Capture - Gruppe zu machen. Der -rSchalter aktiviert erweiterte reguläre Ausdrücke, weshalb der Fehler nicht angezeigt wird. Siehe Warum muss ich Regex-Zeichen in sed maskieren, um als Regex-Zeichen interpretiert zu werden? .

Zweitens platzieren Sie die Erfassungsgruppe am falschen Ort. Wenn ich Sie richtig verstehe, können Sie dies tun:

sed -e 's!^\(\s*access_log\)[^;]*;!\1 /dev/stdout;!' your_file

Beachten Sie die Verwendung von !Regex-Trennzeichen, um die Schrägstriche nicht zu umgehen /dev/stdout.


Danke, funktioniert wunderbar! Ich kann dies noch nicht als akzeptiert markieren, werde aber in 9 Minuten zurück sein, um dies zu tun.
— Abe Voelker

1
@ BeVoelker Gern geschehen. Es freut mich, dass ich helfen konnte.
— Joseph R.

5

In Ihrem regulären Ausdruck sollten Sie wissen, dass dies \No.der Rückverweis auf Muster in Klammern ist (). So sollte regexp sein's@^(\s*access_log ).*$@\1/dev/stdout/;@'

ich kann anbieten

sed '/access_log/s|/[^;]\+|/dev/stdout|'

TIPP: Unabhängig davon, ob Sie das Muster /innerhalb des Musters verwenden möchten, können Sie es s///für jedes Symbol ändern, das Sie s###beispielsweise möchten


Danke, ich wünschte, ich könnte zwei Antworten akzeptieren! Ich bedaure nicht mehr, die Manpages nicht vollständig gelesen zu haben, bevor ich nach den Lösungen um Hilfe gebeten habe.
— Abe Voelker

3

Warum nicht einfach finden und ersetzen, anstatt es einzufangen? Dh:

sed "/access_log/ s| /.*;| /dev/stdout;|"

Es sucht nach Zeilen, die " access_log" übereinstimmen, und ersetzt " " in allen Zeilen, die dies tun, durch /whatever/path/is/there;" /dev/stdout;".

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.