Search code examples
bashsedexecfind-util

find: missing argument to `-exec', even after escaping semicolon


for i in `ls`; do find /path/to/different/project -name $i -type f -exec sed -i "s/var Handlebars/d" {}; done;

I have tried seemingly everything, including escaping the ; after the {}, escaping both ;'s, escaping the quotes, tweaking the sed command - all to no avail. What gives?


Solution

  • (Don't use for i in ls. It will fail if any filename includes whitespace, and it is unnecessary. for i in * does exactly what you want, without the need for a subprocess.)

    The correct syntax is:

    for fn in *; do
      find /path/ -name "$fn" -type f -exec sed ... {} \; ;
    done  
    

    \; is an argument to find. Both {} and ; must appear as individual arguments; if you use {}\; the shell will combine those into one argument and find will treat it as a simple argument to sed.

    The second ; is a shell metacharacter which terminates the find command. Written as above, on three lines, the ; is unnecessary but if you want a one-liner, it will be needed. If you escape it, as \;, it stops being a shell metacharacter, and is simply passed to find as an argument, where it will create an error.