by June 01, 2015

The problem

Replacing all instances of vcr: {} with vcr: { record: :new_episodes }, in all files below spec/features.

Normally this find -exec can come to the rescue, so a reasonable approach might be:

$ find spec/features/ -type f -exec sed -i 's#vcr: {}#vcr: { record: :new_episodes }#' {} \;

Pro-tip: change the delimiter to #

Unfortunately we run in to trouble here: It just so happens that {} is the sequence find's -exec switch uses to substitute in filenames.

Well, surely we can just escape the {} through find, right?

$ find spec/features/ -type f -exec sed -i 's#vcr: \{\}#vcr: { record: :new_episodes }#' {} \;`
sed: -e expression #1, char 45: Invalid content of \{\}

Not quite. Now the \{\} are being passed straight through to sed, including the \s, and unfortunately when sed sees escaped {}s it assumes them to be a consecutive occurrence matcher.

The solution

Sometimes it's best to just ditch -exec altogether, and use the ever versatile xargs:

$ find spec/features/ -type f -print0 | xargs -0 sed -i 's#vcr: {}#vcr: { record: :new_episodes }#'

Need help with your project?

We specialize in Ruby on Rails and JavaScript projects. Code audits, maintenance and feature development on existing apps, or new application development. We've got you covered.

Get in touch!