我对批处理文件和 DOS 还很陌生,但无论如何我希望你能帮助我。
我需要复制特定文件类型的文件,这些文件现在位于单独的子目录中,每个目录一个这样的文件(但有更多具有不同文件类型的文件)。它们都具有相同的名称,因此当复制到新文件夹时,使用此问题中描述的命令时,要复制的最后一个文件将被以下文件替换:将具有特定扩展名的文件从多个目录复制到一个目录中。
是否可以先将文件名更改为其各自目录的名称,然后使用示例中的命令?或者更好的是,在将文件的新副本放入新目录之前更改其名称,或者在将文件复制到新目录之后但在复制以下文件之前更改其名称?
答案1
好的,这里有一个。您可能需要考虑使用比批处理文件更灵活的方法;一个简单的 C++ 程序会容易得多。批处理不能很好地处理提取目录名称所需的字符串操作。
@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
目前还没有任何硬编码:要使用它,请执行以下操作。
copyfiles.bat <destination> <source> <ext> [ext]
例如
copyfiles.bat "C:\Dest" "C:\Source" .txt .xml .csv .log
编辑(根据第一条评论中的要求)
::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
答案2
根据链接的示例,我扩展了代码,以便将文件名更改为递增的数字,以便所有 xml 文件都使用旧文件名(插入%%~nxf
)加上递增的数字复制到 X:\destination。
@Echo Off
SET /A counter=1
for /R "X:\source" %%f in (*.xml) do (
copy "%%f" "X:\destination\%%~nxf_!counter!.xml"
SET /A counter=!counter!+1
echo !counter!
)
请注意,您不能简单地执行此批处理文件。由于 for 循环中使用了计数器变量,因此必须启用“延迟变量扩展”。
因此,如果你将上面的脚本保存为复制命令您可以按如下方式启动它:
cmd.exe /v:on /c "mycopy.cmd"