Ok, here's one. You might want to consider using something more flexible than a batch file; a simple C++ program would have been much easier. Batch does not play nice with the string manipulation necessary to extract the directory name.
@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET _destination=%~1
SHIFT
SET _source=%~1
SHIFT
SET _cmdstring=dir /b /s
:LoopGetExt
SET _cmdstring=%_cmdstring% "%_source%\*%~1"
SHIFT
IF NOT "%~1"=="" GOTO LoopGetExt
::End LoopGetExt
FOR /F "tokens=*" %%i IN ('%_cmdstring%') DO (
SET _fullpath=%%i
SET _splitpath=!_fullpath:\=^
!
SET _filename=%%~ni%%~xi
FOR /F "tokens=*" %%j IN ("!_splitpath!") DO (
IF NOT "%%j"=="!_filename!" SET _dirname=%%j
)
ECHO "%%i" =^> "%_destination%\!_dirname!_!_filename!"
COPY "%%i" "%_destination%\!_dirname!_!_filename!"
)
ENDLOCAL
At the moment nothing has been hardcoded: to use it, do this.
copyfiles.bat <destination> <source> <ext> [ext]
e.g.
copyfiles.bat "C:\Dest" "C:\Source" .txt .xml .csv .log
EDIT (as per request in first comment)
::copyfiles.bat <destination> <source> <ext> [ext]
::e.g.
::copyfiles.bat "C:\Dest" "C:\Source" .txt .xml .csv .log
@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET _destination=%~1
SHIFT
SET _source=%~1
SHIFT
SET _cmdstring=dir /b /s
:LoopGetExt
SET _cmdstring=%_cmdstring% "%_source%\*%~1"
SHIFT
IF NOT "%~1"=="" GOTO LoopGetExt
::End LoopGetExt
FOR /F "tokens=*" %%i IN ('%_cmdstring%') DO (
SET _fullpath=%%i
SET _splitpath=!_fullpath:\=^
!
SET _filename=%%~ni
FOR /F "tokens=1 delims=. " %%j IN ("!_splitpath!") DO (
IF NOT "%%j"=="!_filename!" SET _dirname=%%j
)
ECHO "%%i" =^> "%_destination%\!_dirname!%%~xi"
COPY "%%i" "%_destination%\!_dirname!%%~xi"
)
ENDLOCAL