sed échoue avec l'erreur "option inconnue à" s "

158

J'essaye d'utiliser

sed -i -e "s/.*seb.*/    \"$ftp_login_template\"/" $ftp_dir

cependant j'obtiens cette erreur:

sed: -e expression #1, char 34: unknown option to `s'

Je ne comprends pas pourquoi puisque cela fonctionne parfaitement:

sed -i -e "s/.*wbspassword.*/    \"wbspassword\": \"$password\",/" $user_conf

Des idées sur ce que je fais mal?

Est-ce que ceci pourrait être le problème? ftp_login_template=\${user}:${password}:24:86::\/var\/lib\/clit.${user}\/downloads:\/bin\/false\"

M. King
la source
8
Le message d'erreur * BSD (y compris OSX) est "mauvais drapeau dans la commande de remplacement:" - l'incluant ici pour rendre cela un peu plus googlable.
tripleee

Réponses:

355

Le problème est avec les barres obliques: votre variable les contient et la commande finale sera quelque chose comme sed "s/string/path/to/something/g", contenant beaucoup trop de barres obliques.

Puisque vous sedpouvez prendre n'importe quel caractère comme délimiteur (sans avoir à déclarer le nouveau délimiteur), vous pouvez essayer d'en utiliser un autre qui n'apparaît pas dans votre chaîne de remplacement:

replacement="/my/path"
sed --expression "s@pattern@$replacement@"

Notez que ce n'est pas à l'épreuve des balles: si la chaîne de remplacement la contient plus tard, @elle sera cassée pour la même raison, et toute séquence de barre oblique inverse comme \1sera toujours interprétée selon les sedrègles. L'utilisation |comme délimiteur est également une option intéressante car sa lisibilité est similaire à /.

Tomas Pruzina
la source
38
Juste une note pour aider les futurs utilisateurs, car j'ai trouvé cette réponse également utile. L'affiche originale contenait probablement quelque chose dans son remplacement (probablement caché dans la variable) qui contenait des barres obliques. Après avoir rencontré la première de ces barres obliques, sed considérait que le remplacement était terminé, et ce qui venait ensuite en option (comme g).
Brian Warshaw
4
Bien fait (n'oubliez pas d'envelopper les expressions variables avec "pas 'sinon vous en aurez beaucoup $contentdans votre résultat final au lieu du contenu de $content:))
1
@AbstractDissonance Peut-être que si vous remplacez un mot de passe ou quelque chose de bizarre ou aléatoire, vous avez toujours @ dedans. Vous devez trouver un délimiteur qui n'est pas contenu dans votre chaîne de substitution.
Xavi Montero
5
@ppumkin remplace simplement les délimiteurs "barre oblique" comme ie: sed -i "s/../../g"avec un caractère différent ie :, sed -i "s@...@...@g"alors le problème des barres obliques multiples devrait disparaître. Et si vous utilisez au "lieu de 'cela devrait fonctionner aussi bien avec les variables à l' intérieur, à savoir: export var1=bar; sed -i "s@foo@${var1}@g". Plus d'informations, vous pouvez trouver dans la superbe documentation sed: grymoire.com/Unix/Sed.html
Egel
1
Voir info sed(source: unix.stackexchange.com/questions/259083/… ): "La syntaxe de la commande s (comme dans un substitut) est 's / regexp / replacement / flags'. Les caractères / peuvent être uniformément remplacés par tout autre caractère unique dans une commande donnée. "
Gabriel Staples