Você pode usar tar ou cpio ou pax (se algum deles estiver disponível) para copiar determinados arquivos, criando diretórios de destino conforme necessário. Com o GNU tar, para copiar todos os arquivos regulares chamados *.txt ou README.* sob o diretório atual para a mesma hierarquia em ../destination :
find . -type f \( -name '*.txt' -o -name 'README.*' \) |
tar -cf - -T - |
tar -xf - -C ../destination
Com apenas find , cp , mkdir e o shell, você pode percorrer os arquivos desejados com find e iniciar um comando shell para copiar cada um deles. Isso é lento e pesado, mas muito portátil. O fragmento de shell recebe o diretório raiz de destino como $0 e o caminho para o arquivo de origem como $1 ; ele cria a árvore de diretórios de destino conforme necessário (observe que as permissões do diretório não são preservadas pelo código abaixo) e copia o arquivo. O trecho abaixo funciona em qualquer sistema POSIX e na maioria das instalações do BusyBox.
find . -type f \( -name '*.txt' -o -name 'README.*' \) -exec sh -c '
mkdir -p "$0/${1%/*}";
cp -p "$1" "$0/$1"
' ../destination {} \;
Você pode agrupar as invocações sh ; isso é um pouco complicado, mas pode ser mensuravelmente mais rápido.
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 {} +
Se você tem bash ≥4 (não sei se o Git Bash é recente o suficiente), não é necessário chamar find , você pode usar o padrão ** glob para recorrer a subdiretórios.
shopt -s globstar extglob
for x in **/@(*.txt|README.*); do
mkdir -p "../destination/${x%/*}"
cp -p -- "$x" "../destination/$x"
done