Sostituisci il contenuto del gruppo di acquisizione regex usando sed


16

Sto provando a modificare il mio file nginx.conf a livello di codice, che contiene una riga come questa:

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

che voglio assomigliare a questo:

        access_log /dev/stdout;

Credo che regex ^\s*access_log([^;]*);acquisirà la /var/log/nginx/access.logparte in un gruppo di acquisizione, ma non sono sicuro di come sostituire correttamente il gruppo di acquisizione con sed?

ho provato

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

ma sto ricevendo l'errore:

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

se provo sed -rallora non c'è errore, ma l'output non è quello che mi aspetto:

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

Sto cercando di essere intelligente con il gruppo di acquisizione e quant'altro e non cercare direttamente "access_log /var/log/nginx/access.log;" nel caso in cui la distribuzione cambi il percorso del file di registro predefinito.


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

@Costas Se dovessi dare una risposta, ti voterei perché funziona anche!
Abe Voelker,

Risposte:


16

Un paio di errori lì.

Innanzitutto, poiché sedutilizza espressioni regolari di base, è necessario \(e \)creare un gruppo di acquisizione. Lo -rswitch abilita le espressioni regolari estese, motivo per cui non si ottiene l'errore. Vedi Perché devo sfuggire ai personaggi regex in sed per essere interpretati come personaggi regex? .

Secondo, stai mettendo il gruppo di acquisizione nel posto sbagliato. Se ti capisco correttamente, puoi farlo:

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

Nota l'uso di !delimitatori regex per evitare di dover sfuggire alle barre in avanti /dev/stdout.


Grazie, funziona meravigliosamente! Non sono ancora in grado di contrassegnarlo come accettato, ma tornerò tra 9 minuti per farlo.
Abe Voelker,

1
@AbeVoelker Prego. Sono felice di poterti aiutare.
Joseph R.,

5

Nel tuo regexp dovresti sapere che \No.è il riferimento posteriore al modello tra parentesi (). Quindi dovrebbe essere regexp's@^(\s*access_log ).*$@\1/dev/stdout/;@'

posso offrire

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

SUGGERIMENTO: se si intende utilizzare /all'interno del patern, si è liberi di cambiare s///per ogni simbolo che si desidera s###ad esempio


Grazie, vorrei poter accettare due risposte! Non mi pento più di non aver letto completamente le pagine man prima di chiedere aiuto dopo aver visto le soluzioni.
Abe Voelker,

3

Invece di catturarlo, perché non trovarlo e fare una sostituzione? Vale a dire:

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

Cerca le righe che corrispondono a " access_log", quindi su qualsiasi riga che lo fa sostituirà " /whatever/path/is/there;" con " /dev/stdout;"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.