當啓用delayed expansion時,通常需要正確地轉義感嘆號才能獲得文字(如^^!
或""
,^!
,以獲得文字!
)。爲什麼在`for/F`或`for/R`參數中不需要跳過感嘆號?
但是,爲什麼在/R
或for
循環命令的開關後立即提供的參數中不必轉義所需的感嘆號?
考慮到上述轉義規則,我創建使用for /R
以下批處理腳本,並作爲參數在其名稱中!
一個目錄(/R
選項後面說明):
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "TARGET=excl^!dir"
set "FILE=empty_%RANDOM%.txt"
echo/
echo creating directory: !TARGET!
mkdir "!TARGET!"
echo placing empty file: !TARGET!\%FILE%
> "!TARGET!\%FILE%" break
echo/
echo adequately escaped `^^!`:
for /R "excl^!dir" %%F in ("*.*") do echo(found item: %%~nxF
for /R excl^^!dir %%F in ("*.*") do echo(found item: %%~nxF
echo/
echo improperly escaped `^^!`:
for /R "excl!dir" %%F in ("*.*") do echo(found item: %%~nxF
for /R excl!dir %%F in ("*.*") do echo(found item: %%~nxF
for /R excl^!dir %%F in ("*.*") do echo(found item: %%~nxF
erase "!TARGET!\%FILE%"
rmdir "!TARGET!"
endlocal
exit /B
令人驚訝的是,該目錄僅列舉了而沒有轉義了!
。這是一個輸出:
creating directory: excl!dir placing empty file: excl!dir\empty_18378.txt adequately escaped `!`: improperly escaped `!`: found item: empty_18378.txt found item: empty_18378.txt found item: empty_18378.txt
我期待目錄的情況下,可以列舉感嘆號其實正確轉義,否則不會;但結果顯示出相反的行爲。
類似的現象出現與for /F
,像下面的腳本,在選項字符串的!
:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "STRING=EXCLAMATION ^! MARK AND CARET ^^ SYMBOL"
echo/
echo normal expansion: %STRING%
echo delayed expansion: !STRING!
echo/
echo adequately escaped `^^!`:
for /F "tokens=1-2 delims=^!" %%K in ("!STRING!") do echo(%%K -- %%L
for /F tokens^=1-2^ delims^=^^! %%K in ("!STRING!") do echo(%%K -- %%L
echo/
echo improperly escaped `^^!`:
for /F "tokens=1-2 delims=!" %%K in ("!STRING!") do echo(%%K -- %%L
for /F tokens^=1-2^ delims^=! %%K in ("!STRING!") do echo(%%K -- %%L
for /F tokens^=1-2^ delims^=^! %%K in ("!STRING!") do echo(%%K -- %%L
endlocal
exit /B
輸出看起來是這樣的,奇怪:
normal expansion: EXCLAMATION MARK AND CARET SYMBOL delayed expansion: EXCLAMATION ! MARK AND CARET^SYMBOL adequately escaped `!`: EXCLAMATION -- MARK AND CARET EXCLAMATION -- MARK AND CARET improperly escaped `!`: EXCLAMATION -- MARK AND CARET^SYMBOL EXCLAMATION -- MARK AND CARET^SYMBOL EXCLAMATION -- MARK AND CARET^SYMBOL
在這裏,我期望整個字符串被拆分我正好兩個令牌:EXCLAMATION
和MARK AND CARET^SYMBOL
。但第二個標記太短,從插入符號^
開始的所有內容都缺失;所以我得出這樣的結論:用於逃避!
的^
是從字面上理解的。沒有(或窮人)逃跑,返回的令牌是預期的。
代碼中沒有什麼需要延遲擴展。在一組行中使用延遲擴展,一個邏輯行分割多於一個物理行(如'for'或'if'命令中的多個命令)或一行上的多個命令*當您更改變量的值時在該塊內,並希望在該塊內使用它*。 – 2016-09-22 22:32:05
是的,我知道,@Noodles;這些腳本只是爲了證明這種奇怪的行爲... – aschipfl