copy files with diresctory hirarchy

I have a directory x and in that I have x.cpp and a directory named Y

and in y I have y.cpp and so on. and some other files too in those directories.

How can I copy only *.cpp files in whole x directory hirarchy to a different location with the same hirarchy?

I mean the whole x directory hirarchy with all *.cpp files and sub-directory names need to be copied to different location.

Any idea?

Below is the correct version which works well as per your needs, I should have edited this post only instead of putting a new post, any ways, you can run the script and modify as per your needs.

Regards,
Tayyab

This might also work, and is a little cleaner.

#!/bin/sh

INDIR=x
OUTDIR=y

# copy only directories with "*cpp" filenames
find $INDIR -type f -name "*cpp" -exec dirname {} \; |
  sed -e "s/^\($INDIR\)\(.*\)/$OUTDIR\2/g" | xargs mkdir -p

# copy all "*cpp" files to new directory hierarchy
for FILE in `find $INDIR -type f -name "*cpp"` ; do
  NEWFILE=`echo $FILE | sed -e "s/^\($INDIR\)\(.*\)/$OUTDIR\2/g"`
  cp -p $FILE $NEWFILE
done

With recursive function, which was missing in earlier version:

#! /bin/ksh

inDir="/home/admin/temp1"       #your source directory goes here
outDir="/home/admin/temp"       # your taget directory goes here
let count=0

#Copy *.cpp files from your source directory to the target, if any
cp $inDir/*.cpp $outDir 2>/dev/null

#Function, which copies *.cpp of each directory recursively

cpfiles () {
dir=$1
if [[ ! -d $outDir/$dir ]]; then
        mkdir $outDir/$dir
fi

ext=""

for filename in $inDir/$dir/*; do
        if [[ -d $filename ]]; then
                a=${filename#$inDir/}
                cpfiles $a
        else
                ext=`echo $filename | cut -d. -f2`
                if [[ $ext = "cpp" ]]; then
                        cp $filename $outDir/$1
                        let count=$count+1
                fi
        fi
done
}

# Only directories are listed, if you have -d option you can only use
# ls -d instead of following command in loop

for dirname in `ls -l $inDir | grep '^d' | awk '{print $9}'` ; do
           cpfiles $dirname
done

echo "$count files copied" 2>&1

Any suggestions would be highly appreciated.

Regards,
Tayyab

cd <source directory>
find . -type f -name "*.cpp" | cpio -pmd <destination directory>

With GNU cp

$ cd <source directory>
$ find -type f -exec cp --parents {} <destination directory> \;

Hi ,
All those suggestions worked, except I couldn't test Hitori's, I only have Sun OS 5.7.

Thanks a lot guys, I liked

find. -type f -name "*.cpp" | cpio -pmd <destination directory> by reborg !

I nener knew about cpio until today!

Yes right, Reborg's suggestion was fast and clean.