2

I have a bunch of text files (named install*) in which I need to replace the expression curl -L with the expression curl -k -L. I am on OS X 10, Yosemite.

The following attempts don't work:

sed -e  "s/'curl -L'/'curl -k -L'/g" install*

sed -i '' -e "s/'curl -L'/'curl -k -L'/g" install*

The contents of the files are shown (as if I had typed cat), but replacement isn't performed.

What am I doing wrong?

mklement0
  • 382,024
  • 64
  • 607
  • 775
thiagoveloso
  • 2,537
  • 3
  • 28
  • 57

2 Answers2

1

You need -i.

GNU sed uses -i without arguments to mean "replace in-place".

BSD sed needs an empty argument, so you'll have to use sed -i '' -e '...' install*

There's no portable way to do it with sed...

izabera
  • 659
  • 5
  • 11
  • It runs but still doesn't affect the files. I have edited the question to reflect this extra attempt. – thiagoveloso May 07 '15 at 01:40
  • 2
    Good pointer re difference between GNU and BSD sed, but `-i` by itself - _with our without option-argument_ - means "update in place" - the option-_argument_ simply specifies a suffix (filename extension) to apped to a _backup_ of the original file. Since GNU `sed` considers this option-argument _optional_, `-i` is sufficient to say "create no backup file", whereas BSD `sed` considers the option-argument _mandatory_, so `-i ''` must be used to express the same thing. – mklement0 May 07 '15 at 02:24
1

Your problem is that you're nesting quoting mechanisms (delimiters) when you shouldn't.

Generally, you should use single quotes to enclose an sed script as a whole:

sed -i '' -e 's/curl -L/curl -k -L/g' install*

By using single quotes, the script is protected from accidental interpretation by the shell.
If you do want the shell to interpret parts of a sed script beforehand, splice those parts in as double-quoted strings.

To sed's s function, it is / that acts as the delimiter - no additional quoting of the strings between / instances should be used, and your use of ' simply causes sed to consider these single quotes part of the regex to match / the replacement string. (As an aside: you're free to choose a delimiter other than /).

That said, if you do need to force interpretation of certain characters as literals, use \-escaping, such as using \. in the regex to represent a literal . This is the only quoting mechanism that sed itself supports.

However, in your particular case, neither the string used in the regex nor the string used as the replacement string need escaping.

For a generic way to escape strings for use as literals in these situations, see https://stackoverflow.com/a/29613573/45375.

Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775