Using literal empty curly braces {} inside sed command from find -exec

findsed

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?

Best Answer

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:

Related Question