When I don't need to adjust destination filenames I can do something like this:
$ find -type f -name '*.pat' -print0 | xargs -O cp -t /path/to/dest
It is safe because the filenames may even contain newline characters.
$ find -type f -name '*.pat' -print0 | cpio -p -0 -d /path/to/dest
Now I have the problem that the destination is a VFAT filesystem ... thus certain characters are just not allowed in filenames (e.g. '?'). That means that I have to adjust the destination filenames.
for i `find -type f -name '*.pat'` ; do cp "$i" `echo $i | sed 's/?/_/'` done
works only for filenames without spaces - I could change IFS to just newline - but how to set '\0' as IFS?
And still - the for loop leads to as much forks/execs (of mv/sed) as you have files - which is much more excessive than the few forks/execs needed for the two examples in the beginning.
What are the alternatives to solve that problem?