繁体   English   中英

批量在for循环中设置变量

[英]Setting up variable in for loop in batch

最近两天,我只用很少的代码就可以解决问题。 在这种情况下,我无法在for循环中设置变量。 我想将文件名分配给变量以进行字符串操作。

echo off
for  /f  %%a IN ('dir /b *_ah.ttf') DO (
set /a fName=%%~na 
echo %fName% 
)

当我echo fName变量时,我仅重复获得最后一个文件名的次数,用于for循环计数。

(我想将此变量作为参数传递给某些批处理文件,如下所示

ttfhnt --strong-stem-width=D -i %%a  %fName:~0,-3%.ttf

但由于上述问题而失败)

有人可以帮我吗?

当cmd解析器读取一行或一行行(括号内的代码)时,所有读取的变量都将替换为变量内的值, 然后再开始执行代码。 如果块中代码的执行更改了变量的值,则无法从同一块内部看到此值,因为不存在对变量的读取操作,因为已将其替换为变量中的值。

在将多个命令与&串联的行中可以看到相同的行为。 该行被完全解析,然后执行。 如果前几个命令更改了变量的值,则后几个命令将不能使用此更改的值,因为读取操作将被替换。

要解决此问题,您需要启用延迟扩展,并在需要时将语法从%var%更改为!var! ,向解析器指示读取操作需要延迟直到命令执行为止。

set /A仅用于算术运算

setlocal enabledelayedexpansion
for  /f "delims=" %%a IN ('dir /b *_ah.ttf') DO (
    set "fName=%%~na"
    echo "!fName!" "!fName:~0,-3!"
)

编辑以适应评论

尽管for命令能够执行命令(在OP代码中, dir... ),检索其输出然后在此输出中的行上进行迭代,但命令的原始原因是在一组文件上进行迭代。 以这种形式,代码可以写成

setlocal enabledelayedexpansion
for  %%a IN ("*_ah.ttf") DO (
    set "fName=%%~na"
    echo "!fName!" "!fName:~0,-3!"
)

现在, for命令的replaceable参数将遍历指示的文件集。 for /?执行for /?获取所有命令选项的列表)。

但是作为foxidrive点,扩展延迟的问题是惊叹号。 没有延迟的扩展,它们是另一个正常的字符,但是在延迟的扩展中,当包含/分配它们的值时,它们经常成为问题。

快速测试

@echo off
    setlocal enabledelayedexpansion

    set "test=this is a test^!"
    echo ---------------------
    set test
    echo ---------------------
    echo delayed : !test!
    echo normal  : %test%
    for /f "delims=" %%a in ("!test!") do echo for     : %%a

将会呈现

---------------------
test=this is a test!
---------------------
delayed : this is a test!
normal  : this is a test
for     : this is a test

显然,当该值是文件名时,此行为将使代码查找或不查找文件。

根据情况的不同,可以使用不同的解决方案,但通常涉及延迟扩展行为的激活/取消激活(请注意, endlocal会从先前的setlocal删除环境变量的任何更改)。

@echo off
    setlocal enabledelayedexpansion

    set "test=this is a test^!"
    echo ---------------------
    set test
    echo ---------------------
    echo delayed : !test!

    rem Commuted to no delayed expansion
    setlocal disabledelayedexpansion
    echo normal  : %test%
    endlocal

    rem Cancelled the initial enable delayed expansion
    for /f "delims=" %%a in ("!test!") do endlocal & echo for     : %%a

    rem The last endlocal has removed the changes to the variable
    echo no data : [%test%]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM