我想要一个批处理文件,将文本文件中列出的所有文件从一个目标复制到另一个目标。源目标可能有多个子文件夹,我希望批处理能够在每个子文件夹中搜索文件名。
我不想复制文件夹本身,只复制文件。
我有以下代码,但它无法识别(%file_list%)
set src=c:\files\sourcefolder\
set dst=c:\files\destinationfolder\
set file_list=c:\\files\files.txt
for /r "%src%" %%i in (%file_list%) do copy "%%i" "%dst%" >notcopied.txt
我还希望文件写一个名为'notcopied.txt'的文本文件,这样我就可以看到源文件夹中是否有任何必需的文件。我希望将该文件写入目标文件夹。
例如:
files.txt contains
File1.pdf
File2.pdf
File3.pdf
源文件夹包含
File1.pdf
File2.pdf
然后notcopied.txt将显示
File3.pdf
感谢您的任何见解。
答案 0 :(得分:2)
首先,您需要启用扩展命令行
SETLOCAL ENABLEEXTENSIONS
因此您可以使用扩展的 FOR 循环。其次,您需要启用环境变量的延迟扩展
SETLOCAL ENABLEDELAYEDEXPANSION
因此您可以检查以后是否找到了搜索到的文件。
结果如下:
@echo off
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
SET src=.\sourcefolder\
SET dst=.\destinationfolder\
SET file_list=.\files.txt
FOR /F %%f IN (%file_list%) DO (
SET found=false
FOR /F "usebackq" %%s IN (`where /R %src% %%f`) DO (
SET found=true
echo "%%s => %dst%\%%f"
@copy /y "%%s" "%dst%\%%f"
)
IF "!found!" == "false" (
echo %%f is not found!
)
)
变量%found%
需要 ENABLEDELAYEDEXPANSION ,如果%found%
始终为false
。
此外,要在运行时扩展环境,必须使用!found!
语法。
您可以将其称为
batch.bat > result.log
,结果将写入档案result.log
更新:这是一个没有变量found
的bacth版本,以及来自 @aschipfl 的建议:
@echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET "src=.\sourcefolder\"
SET "dst=.\destinationfolder\"
SET "file_list=.\files.txt"
FOR /F "usebackq eol=| delims=" %%f IN ("%file_list%") DO (
rem just searching to find out existense of file
WHERE /Q /R "%src%" "%%f"
IF "!ERRORLEVEL!" == "0" (
FOR /F "usebackq eol=| delims=" %%s IN (`WHERE /R "%src%" "%%f" 2^> nul`) DO (
echo "%%s => %dst%\%%f"
@copy /y "%%s" "%dst%\%%f"
)
) ELSE (
echo %%f is not found!
)
)
此版本可以处理文件名中带有space
符号的文件。
但是这两种解决方案都有相同的限制:sourcefolder
不能在名称中包含任何空格。由于某种原因,命令WHERE /R "%src%" "%%f"
不起作用,而WHERE /R %src% "%%f"
正常工作。
UPDATE2 :这是产生result.log
的版本:
@echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET "src=.\sourcefolder\"
SET "dst=.\destinationfolder\"
SET "file_list=.\files.txt"
SET "out=.\result.log"
echo > %out%
FOR /F "usebackq eol=| delims=" %%f IN ("%file_list%") DO (
rem just searching to find out existense of file
WHERE /Q /R %src% "%%f"
IF "!ERRORLEVEL!" == "0" (
FOR /F "usebackq eol=| delims=" %%s IN (`WHERE /R %src% "%%f"`) DO (
echo "%%s => %dst%\%%f" >> %out%
@copy /y "%%s" "%dst%\%%f"
)
) ELSE (
echo %%f is not found! >> %out%
)
)