Estou tentando editar meu arquivo nginx.conf programaticamente, que contém uma linha como esta:
access_log /var/log/nginx/access.log;
que eu quero ficar assim:
access_log /dev/stdout;
Acredito que o regex ^\s*access_log([^;]*);
capturará a /var/log/nginx/access.log
parte em um grupo de captura, mas não sei como substituir corretamente o grupo de captura por sed?
eu tentei
echo " access_log /var/log/nginx/access.log;" | sed 's/^\s*access_log([^;]*);/\1\\\/dev\\\/stdout/'
mas estou recebendo o erro:
sed: -e expression #1, char 45: invalid reference \1 on `s' command's RHS
se eu tentar sed -r
, não haverá erro, mas a saída não é o que eu espero:
/var/log/nginx/access.log\/dev\/stdout
Estou tentando ser inteligente com o grupo de captura e outros enfeites e não procurar diretamente por "access_log /var/log/nginx/access.log;" caso a distribuição altere o local padrão do arquivo de log.
sed '/access_log/s|/[^;]\+|/dev/stdout|'
Respostas:
Alguns erros lá.
Primeiro, como
sed
usa expressões regulares básicas, você precisa\(
e\)
deve criar um grupo de captura. A-r
opção permite expressões regulares estendidas e é por isso que você não recebe o erro. Consulte Por que preciso escapar caracteres regex no sed para ser interpretado como caracteres regex?.Segundo, você está colocando o grupo de captura no lugar errado. Se eu entendi direito, você pode fazer o seguinte:
Observe o uso de
!
como delimitadores de expressão regular para evitar a necessidade de escapar das barras/dev/stdout
.fonte
Em sua regexp, você deve saber que
\No.
é a referência anterior ao padrão entre colchetes()
. Então regexp deve ser's@^(\s*access_log ).*$@\1/dev/stdout/;@'
Eu posso oferecer
DICA: Se você pretende usar
/
dentro do padrão, pode mudars///
para cada símbolo que desejar,s###
por exemplofonte
Em vez de capturá-lo, por que não encontrá-lo e fazer uma substituição? Ou seja:
Ele procura por linhas que correspondam "
access_log
" e, em qualquer linha que o substitua, "/whatever/path/is/there;
" por "/dev/stdout;
"fonte