243

I'm trying to use

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

however I get this error:

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

I don't understand why since this works perfectly:

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

Any ideas as to what I'm doing wrong?

Could this be the problem? ftp_login_template=\${user}:${password}:24:86::\/var\/lib\/clit.${user}\/downloads:\/bin\/false\"

codeforester
  • 39,467
  • 16
  • 112
  • 140
Goulash
  • 3,708
  • 6
  • 29
  • 48
  • 9
    The *BSD error message (including OSX) is "bad flag in substitute command:" -- including it here to make this somewhat more googlable. – tripleee Oct 20 '15 at 08:35
  • 1
    Duplicate of https://stackoverflow.com/questions/27787536/how-to-pass-a-variable-containing-slashes-to-sed – tripleee Sep 25 '20 at 09:14

1 Answers1

514

The problem is with slashes: your variable contains them and the final command will be something like sed "s/string/path/to/something/g", containing way too many slashes.

Since sed can take any char as delimiter (without having to declare the new delimiter), you can try using another one that doesn't appear in your replacement string:

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

Note that this is not bullet proof: if the replacement string later contains @ it will break for the same reason, and any backslash sequences like \1 will still be interpreted according to sed rules. Using | as a delimiter is also a nice option as it is similar in readability to /.

Elijah Lynn
  • 12,272
  • 10
  • 61
  • 91
Tomas Pruzina
  • 8,397
  • 6
  • 26
  • 39
  • 51
    Just a note to help future users, as I found this answer helpful, as well. The original poster most likely had something in his replacement (most likely hidden in the variable) that contained forward slashes. After the first one of those slashes was encountered, sed considered the replacement terminated, and whatever came next as an option (such as `g`). – Brian Warshaw Feb 21 '14 at 14:05
  • Ahh yes, after looking 10 times i see the slash. So how do i fix that then? – Piotr Kula Oct 31 '14 at 22:00
  • 5
    Nicely done (Just remember to wrap variable expressions with `"` not `'` otherwise you'll get a lot of `$content` in your end result instead of the content of `$content` :) ) –  Jan 08 '16 at 13:41
  • I still have the same problem on windows: sed: -e expression #1, char 27: unknown option to `s'. I replaced the / with @ and even #... – AbstractDissonance Mar 14 '17 at 18:15
  • 1
    @AbstractDissonance Maybe if you are replacing a password or something weird or random you still have @ in it. You must find a delimiter which is not contained in your substitution string. – Xavi Montero Apr 06 '17 at 11:09
  • 11
    @ppumkin just replace "forward slash" delimiters like i.e.: `sed -i "s/../../g"` with different character i.e: `sed -i "s@...@...@g"`, then the problem of multiple slashes should disappear. And if you use `"` instead of `'` it should also works well with variables inside, i.e.: `export var1=bar; sed -i "s@foo@${var1}@g"`. More info you can find into awesome sed documentation: http://www.grymoire.com/Unix/Sed.html – Egel Jun 28 '17 at 15:45
  • 3
    See `info sed` (source: https://unix.stackexchange.com/questions/259083/replace-unix-path-inside-a-file/259087#259087): **"The syntax of the s (as in substitute) command is ‘s/regexp/replacement/flags’. The / characters may be uniformly replaced by any other single character within any given s command."** – Gabriel Staples Mar 18 '20 at 05:19
  • @Egel Thanks for that tip, I was using var subsitution and the var was a `http://` link with slashes. I was not able to use `@` as I got an "unterminated S command" but was able to use a pipe, `|` as a delimiter per @GabrielStaples comment, and that still has nice readability too. – Elijah Lynn Apr 22 '20 at 09:20
  • The one that created the error message for this issue was pure evil genius! – Dan Nemes Jan 13 '22 at 15:10
  • The @ use works wonders with ubuntu 22.04. I tried using variables like `sed -i 's/$old_text/$new_text/g'` but it didnt work. – Marco Montevechi Filho Aug 18 '22 at 15:12
  • I could solve this problem by escaping slashes – pascalre Feb 22 '23 at 12:52