我有一个问题如何在批处理文件中将多个文件设置为变量?我尝试用下面的脚本做一些事情:
move c:\*.gpg q:\
for %%F in ("q:\*.gpg") do (set file=%%~nxF)
if exist q:\*.gpg echo done copying files: %file%
以上只适用于一个文件。如果有两个以上它只回声其中一个。如何在一行中回显所有复制的文件?
答案 0 :(得分:3)
您的代码存在多个问题
for %%F in ("q:\*.gpg") do (set file=%%~nxF)
if exist q:\*.gpg echo done copying files: %file%
首先,您在每个循环中为变量文件分配新值,然后每次都覆盖它而不做任何事情。因此,循环file
之后只包含最后一个循环中的值。将echo
部分移动到循环内部而不是
另一个问题是默认情况下变量在解析时扩展。您需要enable delayed expansion并使用!
而不是%
来使其在运行时展开
Setlocal EnableDelayedExpansion
for %%F in ("q:\*.gpg") do (
set file=%%~nxF
echo done copying file: !file!
)
如果您想一次回显所有文件,请将file
变量设置为包含文件列表
for %%F in ("q:\*.gpg") do (
set file=!file!, %%~nxF
)
echo done copying files: %file%
存在的文件检查是多余的。您可以在移动后检查退出代码,如果文件未移动则退出。
答案 1 :(得分:1)
变量不是常数所以请记住激活扩展延迟变量,这里必须延迟变量file
的扩展。
延迟扩展会导致变量在执行时而不是在解析时展开,此选项会使用 SETLOCAL
命令打开。如果延迟扩展有效,则可以使用 !variable_name!
引用变量(除了正常的 %variable_name%
)
FOR
循环时, 延迟变量扩展通常很有用,通常整个 FOR
循环是即使它跨越批处理脚本的多行,也作为单个命令进行评估。
这是 FOR
循环的默认行为:
示例:
@echo off
setlocal
:: count to 5 storing the results in a variable
set _tst=0
FOR /l %%G in (1,1,5) Do (echo [%_tst%] & set /a _tst+=1)
echo Total = %_tst%
C:\> demo_batch.cmd
[0]
[0]
[0]
[0]
[0]
Total = 5
请注意,当 FOR
循环结束时,我们得到正确的总数,因此变量正确递增,但在循环的每次迭代期间
变量停留在它的初始值0
与 EnableDelayedExpansion
相同的脚本会给出相同的最终结果,但也会显示中间值:
@echo off
setlocal EnableDelayedExpansion
:: count to 5 storing the results in a variable
set _tst=0
FOR /l %%G in (1,1,5) Do (echo [!_tst!] & set /a _tst+=1)
echo Total = %_tst%
C:\> demo_batch.cmd
[0]
[1]
[2]
[3]
[4]
Total = 5
请注意,在for循环中,我们使用 !variable!
而不是 %variable%
。
您的批处理脚本可以这样写:
@echo off
Set "Ext=*.gpg"
set /a Count=0
Setlocal EnableDelayedExpansion
for %%F in ("q:\%Ext%") do (
SET /a Count+=1
set "file=%%~nxF"
echo Done copying file [!Count!] : !file!
)
SET /a "COUNT_TOT=%Count%"
ECHO.
ECHO Total of [%EXT%] files(s) : %Count% file(s)
pause