6

I'm wondering if it is possible to include empty curly braces {} inside a sed replacement called from a find -exec.

An example:

find "$dir" -type f -name "*" -exec sed -i s/hello{}a/hello{}b/g '{}' +

This brings up the error message of duplicate {}:

find: Only one instance of {} is supported with -exec ... +

Is there a way to keep {} in the sed command and to be seen as literals, not as replacements for the files that find finds?

1
  • 1
    As an aside, you don't need single quotes around {}, and -name "*" is superfluous.
    – Wildcard
    Feb 26, 2016 at 3:08

2 Answers 2

7

In this case, you can work around find's exec grammar by capturing a brace expression and using a back reference in the replacement text:

$ cat f1 f2
f1: hello{}a
f2: hello{}a
$ find . -type f -exec sed -i 's/hello\([{][}]\)a/hello\1b/g' '{}' +
$ cat f1 f2
f1: hello{}b
f2: hello{}b

Or, more simply (as noted in the comments):

find "$dir" -type f -exec sed -i 's/\(hello[{]}\)a/\1b/g' {} +

Note that the -i option for Sed is not portable and will not work everywhere. The given command will work on GNU Sed only.

For details, see:

3
  • If you're already using a backreference, there's no reason not to include hello in it. And putting one curly brace in brackets should be enough; you don't need to do both.
    – Wildcard
    Feb 26, 2016 at 3:04
  • (And you don't need single quotes around {}.)
    – Wildcard
    Feb 26, 2016 at 3:04
  • 1
    find "$dir" -type f -exec sed -i 's/\(hello[{]}\)a/\1b/g' {} +
    – Wildcard
    Feb 26, 2016 at 3:10
0

For one thing, you're using + which means that -exec can put multiple arguments in place of {}. There's no way this is what you intended when combined with your sed command, and it's possible (though very implementation-dependent) that you can get the result you want by simply removing the +.

However the general way to do this is by using sh -c:

find "$dir" -type f -exec sh -c 'sed -i "s/hello$1a/hello$1b/g" "$1"' sh {} \;
2
  • 1
    I should have been more clear in my original question. I do want multiple arguments. I want the {} in the sed command to be seen as literal braces, not as replacements for the files the find command finds.
    – mrbnnny
    Feb 26, 2016 at 2:43
  • @mrbnny, fair enough. In that case Barefoot IO's answer is what you need (though it can be simplified—see my comments on that answer).
    – Wildcard
    Feb 26, 2016 at 3:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .