我试图在网络路径中搜索包含 152,000 个文档的文件夹,要搜索的文件列表为 1500 个,但 5 小时后仅找到 50 个文档。
此脚本是由另一位帮助过我的用户编写的。我正在尝试看看是否有任何方法可以加快速度:
@echo off
for /f "usebackq delims=" %%a in ("C:\cleanup\addr.txt") do (
for /r "Z:\Attachments\PDF\" %%b in ("%%a*") do xcopy "%%b" "C:\cleanup\XMLFix\%%~pb" /s
)
pause
我认为该脚本将使用第一个文件名搜索 152,000 个文档,直到找到匹配项,然后再次在 152,000 个文档中搜索第二个文档,依此类推。
是否可以这样写,以便将所有文件名保存在缓冲区中,并仅搜索 152,000 个文档一次?
答案1
这尚未经过测试,但我认为它会起作用,而且速度应该相对较快。根据您当前的方法每个文件大约需要 6 分钟,我预计此方法应该需要不到 10 分钟才能完成。它只读取一次整个文件夹层次结构,然后一次性检查所有 addr.txt 条目的结果。
@echo off
pushd "c:\cleanup"
:: Prepare addr.txt to be used as /g option for FINDSTR
(for /f "usebackq delims=" %%F in ("addr.txt") do echo \\%%~nxF) >addr.txt.mod
:: Get a list of full paths to all files in hierarchy
dir /b /a-d /s "z:\attachments\pdf\*" >files.txt
:: Match files in files.txt against files in addr.txt.mod
for /f "delims=" %%F in ('findstr /ileg:addr.txt.mod files.txt') do (
REM %%F contains the full path of a matching file
xcopy "%%F" "C:\cleanup\XMLFix%%~pF"
)
:: Delete temp files
del addr.txt.mod files.txt
popd
答案2
使用一组 for 循环确实会非常慢,唯一的原因是即使找到一个文件,它也会继续在其余 152000 个文档中搜索同一个文件。因此花费的时间是 1500x152000。
VBScript 可以更快地完成此操作,因为您可以跳出循环。
即使文件列表可以缩小到几个部分,如果您事先知道文件不会在特定的位置,它也不会搜索所有内容,整体可能会得到优化,但这可能不是必要的。
最后,考虑到通过网络执行此操作会极大地减慢速度,将所有 152000 个文档复制到本地并在那里执行搜索和复制可能是件好事。
如果您确实编写了 VBScript 并且必须通过网络执行此操作,请确保 VBScript 编辑文件列表并从列表中删除已找到的任何文件。这将确保您可以随时停止脚本并在稍后恢复。
虽然 SuperUser 不是脚本编写服务,但我可以为您提供所需的命令:
' Copy files to...
sDestination = "c:\some\path"
' get filenames in folder
sPath = "c:\some\path"
Set fso = createobject("Scripting.FileSystemObject")
Set oFolderContent = fso.GetFolder(sPath)
' open textfile and read its content
set oFileList = fso.OpenTextFile(sFilename, 8, false)
' Loop to go through all files in a folder
For Each oFile In oFolderContent.files
' Loop to go through all folders in a folder
For Each oFile In oFolderContent.folders
'break out of a for loop
exit for
'copy a file
fso.CopyFile oFile, sDestination
如果这一切太复杂,我建议从 Stack Overflow 寻求一些帮助。