0

我想寫一個批處理文件,需要一些參數,其後是一個或多個可選的文件名(可能包含通配符),並且在某些時候處理每個可選文件名,但for命令不斷嘗試擴展他們,所以即使只是印刷他們也無濟於事。防止Windows命令解釋程序(FOR)將列表視爲通配符?

我檢查了幫助(for /?),但似乎沒有任何開關來防止這種情況發生。我嘗試使用單引號,雙引號和後引號以及/f,但似乎沒有任何效果。

正如人們所期望以下命令作品:

> for %i in (foo bar baz) do @echo %i 
foo 
bar 
baz 

下面的命令並不:

> for %i in (foo bar baz really?) do @echo %i 
foo 
bar 
baz 

下,更不能:

> ren > reallyz 
The syntax of the command is incorrect. 

> dir /b really* 
reallyz 

> for %i in (foo bar baz really?) do @echo %i 
foo 
bar 
baz 
reallyz 

是否有讓Windows命令解釋器將傳遞的列表視爲字符串,而不是試圖將其解釋爲fil羨慕通配符?

+0

你有沒有試着用插入符號逃逸問號「^」作爲(FOO酒吧巴茲真的^?),你可能用它去撥弄作爲轉義字符的視窗想法是令人費解的,似乎改變時在命令行上運行vs從批處理文件運行。 – JimR

+0

是的,轉義它不起作用(除此之外,即使它已經做到了,那麼當調用批處理文件時,用戶必須記住要跳過它們,這當然是非理想的界面,因爲它與其他傳遞的使用不一致文件名)。 – Synetech

回答

3

否 - 簡單的FOR命令將始終擴展*?通配符字符。

你需要使用GOTO循環來做你想做的。 SHIFT命令可以訪問所有參數。

@echo off 
:argLoop 
if "%~1" neq "" (
    echo %1 
    shift /1 
    goto :argLoop 
) 

最有可能你想要做更多的參數,然後只是打印它們。通常你會將它們存儲在變量的「數組」中以備後用。

@echo off 
setlocal 

set argCnt=1 
:argLoop 
if "%~1" neq "" (
    set "arg.%argCnt%=%~1" 
    set /a argCnt+=1 
    shift /1 
    goto :argLoop 
) 
set /a argCnt-=1 

:: Show Args 
setlocal enableDelayedExpansion 
for /l %%N in (1 1 %argCnt%) do echo arg.%%N = !arg.%%N! 
+0

這很好,我已經考慮過了,但是使用'shift'是不可撤銷的(它永久地改變了參數並且沒有'/ reset'開關或者帶有負面參數),因此我不能再訪問它們(即,後面的兩個強制性參數)放在批處理文件中。我想我可以將前兩個推到env-vars,但是因爲我需要使用路徑字符串選項('%〜dp1','%〜n2' ...),將它們放在env-vars中是不愉快的(你不能用變量來做,也就是說'%〜nfoobar%'不會出於顯而易見的原因)。我不得不通過另一個'for'來運行它,但它值得一試...... – Synetech

+0

@Synetech - 是的,這就是爲什麼我建議將值存儲在變量中。額外的FOR循環是羅嗦的,但它們很快。如果您事先知道需要哪些變體,則可以保存這些值的多個副本,每個副本都有不同的擴展修改器。 – dbenham

+0

好吧,它看起來像它的作品。我改變了可選參數循環的開始索引。我還必須使用* double * -for-loop來訪問每個前兩個參數(例如,在(!arg。%)中%% j的(2,1,2)do中的for/l% %i!)爲第二個回聲[%%〜pnj]'),但至少它工作。 (這已經使本應該是一個相對簡單的批處理文件變得非常複雜,但它比編寫完整的,已編譯的C++程序更簡單 - 我必須研究將zip,7zip等函數集成到最低限度。)謝謝。 – Synetech