71

I want to run a simple command of replacing absolute paths to relative ones inside a CSS file like this:

sed -i 's/\/fonts/../fonts/' /Users/sergeybasharov/WebstormProjects/snap/compiled/Content/stylesheets/style.css

It throws this

sed: 1: "/Users/sergeybasharov/W ...": bad flag in substitute command: 'b'

What can be wrong in this simple script?

Sergei Basharov
  • 51,276
  • 73
  • 200
  • 335
  • There's no `b` anywhere in your command, it must not be what you actually typed. Please paste the actual script. – Barmar Jul 08 '13 at 19:54
  • Yes, really, just used a shorter equivalent :). I have updated to the full variant. – Sergei Basharov Jul 08 '13 at 19:55
  • There's some issue with your quoting that's causing the filename to be included in the subsitute command, but I don't see it in what you've quoted. You're missing a backslash, though. – Barmar Jul 08 '13 at 20:01
  • 2
    The error you're reporting would happen if you had `-e` before the filename or you were missing the `s/\fonts` command at the beginning. It's treating the filename as a sed instruction. – Barmar Jul 08 '13 at 20:03
  • I have read `man` for sed. It's written there that after -i I should use extension that is used to make a backup file. If empty string is provided, then no backup will be created. So I have put it like `-i ''` and it worked. – Sergei Basharov Jul 08 '13 at 20:09
  • possible duplicate of [sed command failing on Mac, but works on Linux](http://stackoverflow.com/questions/4247068/sed-command-failing-on-mac-but-works-on-linux) – Barmar Apr 16 '15 at 10:36

4 Answers4

95

In your command s/\/fonts/../fonts/ is being taken as the parameter to the -i option (the suffix to use for the backup file), and the filename argument is being treated as the editing commands.

You need to specify to disable the backup file creation:

sed -i '' ...

In your example:

sed -i '' 's/\/fonts/../fonts/' /Users/sergeybasharov/WebstormProjects/snap/compiled/Content/stylesheets/style.css

Computers are dumb, they don't figure things out by context, so they can't tell that something beginning with s/ is obviously an editing command, not a suffix.

Arturo Herrero
  • 12,772
  • 11
  • 42
  • 73
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    +1, interesting, in Windows I don't have this problem, I must always use double quotes. – Endoro Jul 08 '13 at 20:19
  • 1
    @Endoro The type of quotes are irrelevant in this case, the important thing is that you have to have an explicit argument there. – Barmar Jul 08 '13 at 20:24
  • 11
    Maybe in `OSX` sed, in `GNU` sed `-i` works without an argument. Good to know :) – Endoro Jul 08 '13 at 20:28
  • 1
    @purpletech See http://stackoverflow.com/questions/4247068/sed-command-failing-on-mac-but-works-on-linux – Barmar Apr 16 '15 at 10:36
  • You're a star Barmar! On a Mac this is what you need. Thanks- – F1Linux Apr 22 '23 at 11:55
41

sed -i 's/\/fonts/../fonts/' is not a valid sed command, try sed -i 's#/fonts#../fonts#'

Endoro
  • 37,015
  • 8
  • 50
  • 63
22

I was having a similar issue. You can install the GNU version of sed in your Mac, called gsed, and use it using the standard Linux syntax.

For that, install gsed using ports (if you don't have it, get it at http://www.macports.org/) by running sudo port install gsed. Then, you can run:

gsed -i 's/old_pattern/new_pattern/g' *
Yves M.
  • 29,855
  • 23
  • 108
  • 144
toquart
  • 394
  • 2
  • 8
8

in sed you can use any character to split, in my case I had / in one of the strings hence the error so I had to replace / with | in the sed split; hope this helps others

STRING1="something/somethingelse"
STRING2="clean"

sed -i '' "s|${STRING1}|${STRING2}|g" FILE
Alexandru
  • 81
  • 1
  • 3