Q:

How to use find and exec to execute multiple commands

I have such a need:
In the directory video, I need to
find ./video -type f | while read myfile; do
    tmp=`basename $myfile`   #example.mp4
    tmp="${tmp/.mp4/.html}"  #example.html
    cp index.html "$tmp"
    sed -i '' "s#sceneFilePath:.*#sceneFilePath: \"$myfile\",#g" $tmp
#done;

Here is my directory:
dir
 |--- video
 |     |--- example.mp4
 |--- index.html
 |--- generateHtml.sh

generateHtml.sh is just like above.
Here is what it does:
find the example.mp4 file in video, then cp index.html example.html and change a string in the example.html.
It works well.
But now for some path and name of .mp4 files, there are some special characters, such as &, , -. It doesn't seem that while read works for these cases.
I've heard that find -exec can handle all of special characters but I don't know how to use it for this case.

A:

See Using Find for detailed discussion.
find ./video -type f -print0 | while IFS= read -r -d '' myfile; do
    tmp=$(basename "$myfile")   #example.mp4  -- consider also tmp=${myfile##*/}
    tmp="${tmp%.mp4}.html"      #example.html
    sed "s#sceneFilePath:.*#sceneFilePath: \"$myfile\",#g" \
      <index.html >"$tmp"
done

Note:

-print0 is used on the find end, and IFS= read -r -d '' is used on the read end; this ensures that all possible filenames (including names with newlines, including names with leading or trailing whitespace) are supported.
The former substitution, which replaced the first instance of .mp4 anywhere in the filename with .html, has been replaced with one which strips .mp4 off the end of the filename, and appends .html.
"$myfile" is quoted in invoking basename. This was your most substantial immediate bug in the original code, as previously a filename could be split into multiple separate arguments to basename.
$() is used instead of backticks. This modern (and yes, POSIX-compliant) command substitution syntax can be easily nested and has much clearer semantics for backslash escapes within.
sed -i, which is nonstandard and nonportable (the above was valid for MacOS but not for GNU), is unneeded here; one can skip the cp and do the transform in-line.

