簡體   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