I'm trying to run a command similar to the one below in a bash script. It should search through all subfolders of $sourcedir and copy all files of a certain type to the root level of $targetdir.#!/bin/bash# These are set as arguments to the script, not hard-codedsourcedir=/path/to/sourcedirtargetdir=/path/to/targetdirfind $sourcedir -type f -name *.type -exec sh -c 'cp $1 $2/`basename $1`' {} $targetdir \;This seems to be pretty close, except that {} isn't being passed in as $2 to -exec sh -c ...I would like to do this as close to the right way as possible, with tolerance for special characters in filenames (specifically single quote characters).Edit: I see people suggesting using xargs or argument chaining. I was under the impression that this is only ok for a limited number of arguments. If I have, for example, thousands of .jpg files I'm trying to copy from a number of gallery directories into a giant slideshow directory, will the solutions chaining arguments still work?Edit 2: My problem was I was missing a _ before my first option to sh in the -exec command. For anyone who is curious about how to make the find command work, add the _ and everything will be fine:find $sourcedir -type f -name *.type -exec sh -c 'cp $1 $2' _ {} $targetdir \;I have accepted an answer below though because it accomplishes the same task, but is more efficient and elegant.
find -exec in bash script with variable expansion
bash;shell script;find;posix
You want to copy files of a specific type, to a specific directory?  This is best done with xargs, and you don't even need that sh.  This is a more appropriate way to do it, should also run more efficiently.find $sourcedir -type f -name *.type | xargs cp -t targetdirIf you need to handle special file names, then use NULL as your seperatorfind $sourcedir -type f -name *.type -print0 | xargs -0 cp -t $targetdir