将文件名设置为批处理文件中的变量

时间:2016-08-12 10:24:45

标签: batch-file

我有一个问题如何在批处理文件中将多个文件设置为变量?我尝试用下面的脚本做一些事情:

move c:\*.gpg q:\
for %%F in ("q:\*.gpg") do (set file=%%~nxF)
if exist q:\*.gpg echo done copying files: %file%

以上只适用于一个文件。如果有两个以上它只回声其中一个。如何在一行中回显所有复制的文件?

2 个答案:

答案 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