Batch file 在递归搜索中使用变量,并在复制文件后停止
我有以下批处理脚本,它接收文件列表并递归地遍历并尝试复制文件:Batch file 在递归搜索中使用变量,并在复制文件后停止,batch-file,recursion,xcopy,Batch File,Recursion,Xcopy,我有以下批处理脚本,它接收文件列表并递归地遍历并尝试复制文件: for /f "usebackq delims=" %%x in (Files.txt) do ( (for /R "\\network\Sites\" %%f in (%%x) do (echo F | xcopy /i "%%f" C:\Files\ )) ) 上述方法确实有效,但即使在复制文件后,它也会在所有子文件夹中循环,这需要大约25分钟,而且考虑到需要复制的文件数量,这不是一个可行的解决方案
for /f "usebackq delims=" %%x in (Files.txt) do
( (for /R "\\network\Sites\" %%f in (%%x) do
(echo F | xcopy /i "%%f" C:\Files\ )) )
上述方法确实有效,但即使在复制文件后,它也会在所有子文件夹中循环,这需要大约25分钟,而且考虑到需要复制的文件数量,这不是一个可行的解决方案。我已经更新了输入文件,使其包含文件结构的附加部分,每个文件都会发生更改,以限制需要搜索的文件夹数量,如下所示:
for /f "delims=, tokens=1,2" %%x in (new2.csv) do
( (for /R "\\network\Sites\%%x\Analyzed\" %%f in (%%y) do
(echo F | xcopy /i "%%f" C:\Files\ )) )
问题是它没有从csv文件中填充%%x
变量,它只是使用路径\\network\Sites\%x\analysisted\
运行命令,但是%%y
变量正确填充了文件名
有什么方法可以让它填充吗?有没有比我在上面所做的(使用for/r
)更好的递归搜索和复制文件的方法
另外,在xcopy成功复制脚本后,是否仍然可以让脚本继续处理下一个文件
我一直在四处寻找类似的问题,但似乎没有一个解决方案在我的情况下起作用
编辑:包括每个请求的更多信息
我试图解决的问题是,我有一个需要从UNC路径复制的文件列表。问题在于,由于要搜索的目录数量较多,采用简单的方法,只需在主目录(\\network\Sites\
)中的所有子文件夹中递归,并尝试复制每个文件大约需要25分钟,由于需要复制的文件数量太多,使其成为不可行的解决方案
files.txt
只是一个文件名列表,扩展名之间用换行符分隔,例如
123hsdfs.ext
4t5efrre.ext
在第二次尝试中,new2.csv
是一种方法,我尝试在文件列表中提取预期目录的额外部分,以减少脚本必须搜索的子文件夹数量。该文件将包含以下内容:
001123hsdfs.ext
002,4t5efrre.ext
我试图将001
和002
放入for/r
循环,但执行时变量填充不正确。在搜索123hsdfs.ext
时,递归循环将使用根文件夹\\network\Sites\001\analysisted\
,它使用的是\\network\Sites\%x\analysisted\
因此,我试图解决的问题分为两部分:
1) 当每个文件的目录部分可以更改时,如何减少搜索的子文件夹数量(理想情况下,只在\\network\Sites
的每个子目录下的analysisd
目录中递归搜索,例如在\\network\Sites\001\analysisted
,\\network\Sites\002\analysisted
等中搜索。因为使用.csv
方法需要大量工作)
2) 成功复制当前文件后,如何继续执行列表中的下一个文件,以避免不必要地搜索文件夹
for /f "usebackq delims=" %%x in (Files.txt) do (
for /R "\\network\Sites\" %%f in (%%x) do (
echo F | xcopy /i "%%f" C:\Files\ && (
goto :break
)
)
)
:break
要仅中断外部循环,请使用子例程。内部循环仍然可以访问外部循环的标记,即使这些标记已包装在子例程或批处理文件中:
for /f "usebackq delims=" %%x in (Files.txt) do (
call :internal
)
exit /b 0
:internal
for /R "\\network\Sites\" %%f in (%%x) do (
echo F | xcopy /i "%%f" C:\Files\ && (
goto :break
)
)
:break
exit /b 0
goto中断了上下文的
,并用于终止其执行。您需要设置本地启用延迟扩展
;但是,要使其正常工作,您需要正则变量来保存每个循环期间的值:
@echo off
setlocal EnableDelayedExpansion
for /f "tokens=1,2 delims=," %%x in (new2.csv) do (
set x=%%x
for /R "\\network\Sites\!x!\Analyzed\" %%f in (%%y) do (
set f=%%f
xcopy /i "!f!" C:\Files\
)
)
@ECHO关闭
SETLOCAL
设置“sourcedir=U:\sourcedir”
设置“destdir=U:\destdir”
::删除开始时的变量$
对于/F“delims=”('set$2^>Nul')中的%%a,请执行设置“%%a=”
对于/f“delims=”(q28480130.txt)中的%%a,请设置“$%%a=Y”
对于(*.*)中的/r“%sourcedir%”%%a,请执行以下操作(
设置“左=”
对于/f“delims==”%%w IN('set$”)DO IF/i“%%w”==“$%%~nxa”(
ECHO找到%%~fa
设置“%%w=”
XCOPY/i“%%~fa”“%destdir%\”>nul
)ELSE(设置为“左=Y”)
如果未定义,则左转到完成
)
没有找到这些文件
设置$
:完成
回音全部完成
目录%destdir%
后藤:EOF
这可能对你有用
您需要更改sourcedir
和destdir
的设置以适应您的环境
我在测试中使用了一个名为q28480130.txt
的文件,其中包含这些数据
123hsdfs.ext
4t5efrre.ext
gx112 juf.lgmm
pq72-99!.kut
ttyopd
$92k.opz
该过程首先从$
开始清除所有环境变量
然后为文件中的每个文件名设置环境变量$filename
然后逐个文件名读取源目录,查看环境中$filename是否为set
。如果是,请将其从环境中清除并复制文件(我保留了相同的选项,并通过使用尾随的\
避免了回显)
首先在每个循环中清除left
,然后设置环境中设置的“文件名”与找到的文件名之间是否存在任何不匹配(因为不匹配意味着尚未找到文件)。因此,如果当..%%w
的完成时,left
保持未定义,然后,最后一个$filename刚刚被找到并从环境中删除,因此我们可以终止该进程
如果未找到任何名称,则这些名称将按常规退出…%%a的循环列出。它们的前缀为$
。对于任何感兴趣的人来说,这都是一个简单的练习。在找到并复制第一个文件后,这会破坏整个脚本。我尝试将:break
放在脚本的顶部,但每次找到并复制文件时,它都会在Files.txt中再次从列表的顶部开始。当成功复制文件时,是否仍有办法让它继续执行Files.txt
中的下一个条目?不幸的是,这与OP中使用%x
的第二个脚本的问题相同