Substituir o conteúdo do grupo de captura de regex usando sed

15

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([^;]*); capture a parte /var/log/nginx/access.log em um grupo de captura, mas não tenho certeza como substituir corretamente o grupo de captura com sed?

Eu tentei

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

mas estou recebendo o erro:

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

se eu tentar sed -r , então não há 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 outras coisas e não pesquisar diretamente por "access_log /var/log/nginx/access.log;" caso a distribuição mude a localização do arquivo de log padrão.

    
por Abe Voelker 02.11.2014 / 21:43

3 respostas

13

Alguns erros lá.

Primeiro, como sed usa expressões regulares básicas, você precisa de \( e \) para criar um grupo de captura. A opção -r ativa as expressões regulares estendidas, e é por isso que você não recebe o erro. Veja .

Em segundo lugar, você está colocando o grupo de captura no lugar errado. Se eu entendi corretamente, você pode fazer isso:

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

Observe o uso de ! como delimitadores regex para evitar a necessidade de escapar das barras em /dev/stdout .

    
por 02.11.2014 / 21:48
5

No seu regexp, você deve saber que \No. é a referência anterior para o padrão entre colchetes () . Então, o regexp deve ser 's@^(\s*access_log ).*$@/dev/stdout/;@'

Eu posso oferecer

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

DICA: Se você pretende usar / dentro do padrão, você pode alterar s/// para cada símbolo que desejar s### , por exemplo

    
por 02.11.2014 / 21:59
3

Em vez de capturá-lo, por que não apenas encontrá-lo e fazer uma substituição? Ou seja:

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

Ele procura por linhas que correspondam a " access_log " e, em qualquer linha que o substitua, " /whatever/path/is/there; " por " /dev/stdout; "

    
por 17.12.2015 / 15:13

Tags