You can use tar or cpio or pax (if any of these is available) to copy certain files, creating target directories as necessary. With GNU tar, to copy all regular files called *.txt or README.* underneath the current directory to the same hierarchy under ../destination:
find . -type f \( -name '*.txt' -o -name 'README.*' \) |
tar -cf - -T - |
tar -xf - -C ../destination
With just find, cp, mkdir and the shell, you can loop over the desired files with find and launch a shell command to copy each of them. This is slow and cumbersome but very portable. The shell snippet receives the destination root directory as $0 and the path to the source file as $1; it creates the destination directory tree as necessary (note that directory permissions are not preserved by the code below) then copies the file. The snippet below works on any POSIX system and most BusyBox installations.
find . -type f \( -name '*.txt' -o -name 'README.*' \) -exec sh -c '
mkdir -p "$0/${1%/*}";
cp -p "$1" "$0/$1"
' ../destination {} \;
You can group the sh invocations; this is a little complicated but may be measurably faster.
find . -type f \( -name '*.txt' -o -name 'README.*' \) -exec sh -c '
for x; do
mkdir -p "$0/${x%/*}";
cp -p "$x" "$0/$x";
done
' ../destination {} +
If you have bash ≥4 (I don't know whether Git Bash is recent enough), you don't need to call find, you can use the ** glob pattern to recurse into subdirectories.
shopt -s globstar extglob
for x in **/@(*.txt|README.*); do
mkdir -p "../destination/${x%/*}"
cp -p -- "$x" "../destination/$x"
done
bashavailable? – enzotib Mar 05 '12 at 16:42robocopycan do that directly on windows (robocopy /S sourcedir targetdir *blah*) – Mat Mar 05 '12 at 16:54