erreur sed: "référence non valide \ 1 sur le RHS de la commande` s '"


104

J'exécute plusieurs commandes de substitution au cœur d'un script colorize pour maven . L'une des sedcommandes utilise une expression régulière qui fonctionne dans le shell comme indiqué ici . L'implémentation actuelle (qui ne fonctionne pas) peut être trouvée ici .

Lorsque j'inclus l'une des variantes de la commande dans le script, un comportement différent se produit:

Variante 1:

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

Adapté au script:

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

Erreur: le shell génère les mêmes informations que si je tapais $ sed. Étrange!?


Variante 2:

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

Adapté au script:

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

Erreur:

sed: -e expression # 7, char 59: référence \ 1 invalide sur le RHS de la commande `s '


10
Dans mon cas, j'avais combiné une -i(option d'édition sur place) avec -re, résultant en -ire(ce qui -iconsommait le refragment comme SUFFIXargument et donc le mode regex étendu n'était pas activé); le changer pour -i -rerésoudre le problème.
Janaka Bandara

Il est également à noter que les guillemets simples 'et doubles "sont traités légèrement différemment, en particulier lors de l'interprétation $vars. Par exemple: sudo sh -c "sed -r -i 's/(^.+_supplicant.conf)/\1${MTXT}/' /etc/network/interfaces"fonctionne, mais: sudo sh -c 'sed -r -i "s/(^.+_supplicant.conf)/\1${MTXT}/" /etc/network/interfaces'ne fonctionne pas.
not2qubit

Réponses:


52

N'avez-vous pas besoin de capturer pour que cela fonctionne? c'est-à-dire pour la variante 2:

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

(Remarque: non testé)

Sans l'argument -r, les références arrière (comme \ 1) ne fonctionneront pas.


42
L' -roption de sed semble être nécessaire pour que la référence arrière fonctionne. Par exemple, sed -e 's/([[:digit:]])/is a digit/'fonctionne mais sed -e 's/([[:digit:]])/\1 is a digit/produit l'erreur d'origine sans -rsed. REMARQUE: le premier appel de sed recherche un littéral (<digit>)et n'est pas un groupe de capture.
Andrew Falanga

Le commentaire sous la réponse est en fait une réponse. Vous pouvez peut-être modifier votre réponse pour la refléter.
miroxlav

@AndrewFalanga vous auriez dû poster votre commentaire en réponse
sanmai

2
Jamais mon erreur a été d'utiliser -ireau lieu d'utiliser -ri. La commande compte :-)
m3nda

54

Cette erreur est courante pour les parenthèses qui ne sont pas échappées. Échappez-les et réessayez.


Par exemple:

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

Doit être échappé avec des barres obliques inverses avant chaque parenthèse:

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

6
Attention, si vous utilisez -rvous n'avez pas à échapper les parenthèses.
qräbnö

13

Si l' option -r/ --regexp-extendedn'est pas fournie, les parenthèses de capture doivent être échappées.


5

Vous avez besoin de vous échapper /après le.

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

Ou si vous ne voulez pas vous soucier de vous échapper, utilisez |

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

ÉDITER:

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

Cela semble raisonnable. Mais cela ne fonctionne pas dans le contexte du script.
JJD

Désolé. La modification soulève l'erreur: sed: -e expression #7, char 58: Invalid range end. La réponse de @Denis fonctionne.
JJD

2
Ok, puis +1 pour la réponse de
@Denis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.