How to copy all HTML files from a directory tree to a single directory

First of all, the shell is globbing the '*' for you. Either escape it with \ or use quotes around *.html

Like so:

find myDir -name "*.html" or find myDir -name \*.html

Skip the use of xargs with find's -exec switch:

find myDir -name "*.html" -exec cp {} ~/otherDir \;

This works because {} takes the place of the file that find found, and is executed once for each match.

Also note that this will flatten the copy of the source directory. Example:

myDir/a.html
myDir/b/c.html

will yield

otherdir/a.html
otherdir/c.html

So you want to copy all the .html files in some source directory and its subdirectories, all to a single directory (i.e. collapsing the hierarchy)?

POSIX Standard:

find myDir -name '*.html' -type f -exec sh -c 'cp "$@" "$0"' ~/otherDir {} +

Note that ~/otherDir becomes parameter 0 to the intermediate shell, which allows for the source files to be precisely "$@". Leaving the target directory outside the shell has the additional advantage that you won't run into quoting issues if that's a variable in the parent shell script (-exec sh -c 'cp "$@" "$0"' "$target").

For older systems that don't have find … -exec … +:

find myDir -name '*.html' -type f -exec cp {} ~/otherDir \;

I your shell is bash ≥4 or zsh:

shopt -s globstar  # only for bash, put it in your `.bashrc`
cp myDir/**/*.html ~/otherDir/

find myDir -name '*.html' -print0 | xargs -0 -J % cp % ~/otherdir