erro sed: “referência inválida \ 1 no RHS do comando` s '”


104

Eu executo vários comandos de substituição como o núcleo de um script colorize para maven . Um dos sedcomandos usa uma expressão regular que funciona e se encontra no shell, conforme discutido aqui . A implementação atual (não funcionando) pode ser encontrada aqui .

Quando incluo uma das variantes do comando no script, ocorre um comportamento diferente:

Variante 1:

$ sed -re "s/([a-zA-Z0-9./\\ :-]+)/\1/g"

Adaptado ao roteiro:

-re "s/WARNING: ([a-zA-Z0-9./\\ :-]+)/${warn}WARNING: \1${c_end}/g" \

Erro: o shell exibe as mesmas informações que se eu digitaria $ sed. Estranho!?


Variante 2:

$ sed -e "s/\([a-zA-Z0-9./\\ :-]\+\)/\1/g"

Adaptado ao roteiro:

-e "s/WARNING: \([a-zA-Z0-9./\\ :-]\+\)/${warn}WARNING: \1${c_end}/g" \

Erro:

sed: -e expressão # 7, char 59: referência inválida \ 1 no RHS do comando `s '


10
No meu caso, eu tinha combinado a -i(opção editar no local) com -re, resultando em -ire(de modo que -iestava consumindo o refragmento como seu SUFFIXargumento e, portanto, o modo regex estendido não estava sendo ativado); alterá-lo para -i -recorrigir o problema.
Janaka Bandara

É importante notar também que as aspas simples 'e duplas "são tratadas de maneira ligeiramente diferente, especialmente na interpretação $vars. Por exemplo: sudo sh -c "sed -r -i 's/(^.+_supplicant.conf)/\1${MTXT}/' /etc/network/interfaces"funciona, mas: sudo sh -c 'sed -r -i "s/(^.+_supplicant.conf)/\1${MTXT}/" /etc/network/interfaces'não.
not2qubit

Respostas:


52

Você não precisa realmente capturar para que funcione? ou seja, para a variante 2:

-r -e "s/WARNING: (\([a-zA-Z0-9./\\ :-]\+\))/${warn}WARNING: \1${c_end}/g" \

(Nota: não testado)

Sem o argumento -r, as referências anteriores (como \ 1) não funcionarão.


42
A -ropção sed parece ser necessária para que a referência anterior funcione. Por exemplo, sed -e 's/([[:digit:]])/is a digit/'funciona, mas sed -e 's/([[:digit:]])/\1 is a digit/produz o erro original sem -rsed. NOTA: a primeira chamada de sed procura um literal (<digit>)e não é um grupo de captura.
Andrew Falanga

O comentário abaixo da resposta é na verdade uma resposta. Talvez você possa editar sua resposta para refleti-la.
miroxlav,

@AndrewFalanga você deveria ter postado seu comentário como uma resposta
sanmai

2
Não importa, meu erro foi usar em -irevez de usar -ri. O pedido é importante :-)
m3nda

54

Este erro é comum para parênteses sem escape. Fuja deles e tente novamente.


Por exemplo:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n(.)/\1/g

Deve ser escapado com barras invertidas antes de cada parêntese:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g

6
Atenção, se você usar -rnão precisa escapar dos parênteses.
qräbnö

13

Se a opção -r/ --regexp-extendednão for fornecida, os parênteses de captura devem ser escapados.


5

Você precisa escapar do /depois do.

sed -e "s/\([a-zA-Z0-9.\/\\ :-]\+\)/\1/g"

Ou se você não quiser se preocupar em escapar, use |

sed -e "s|\([a-zA-Z0-9./\\ :-]\+\)|\1|g"

EDITAR:

sed -e "s|WARNING: \([a-zA-Z0-9.-/\\ :]+\)|${warn}WARNING: \1${c_end}|g"

Parece razoável. Mas não funciona no contexto do script.
JJD

Desculpe. A edição levanta o erro: sed: -e expression #7, char 58: Invalid range end. A resposta de @Denis funciona.
JJD de

2
Ok, então +1 para a resposta de
@Denis
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.