2009-02-11 237 views
46

在Windows批處理文件,報價打交道時你做到以下幾點:在Windows批處理腳本

set myvar="c:\my music & videos"

變量myvar包括存儲與報價。老實說,我覺得這很愚蠢。引號只是爲了告訴字符串開始和結束的位置,而不是存儲爲值本身的一部分。
我該如何防止這種情況發生?

謝謝。

+26

噢,我 - 你正在邁出第一步到真正瘋狂的cmd腳本領域。祝你好運 - 你將需要它。請參閱http://stackoverflow.com/questions/180754/best-free-resource-for-learning-advanced-batch-file-usage/180767#180767瞭解指向一本好書和一些建議的指針。 – 2009-02-11 09:20:12

回答

43
set "myvar=c:\my music & videos" 

注意引號在myvar之前開始。其實很簡單。 備註:除非用引號括起來,否則myvar將不會被回顯,因爲&將作爲命令分隔符來讀取,但它仍然可以作爲路徑使用。

http://ss64.com/nt/set.html

1

必須有引號,如果你設置的文本包括某些字符,包括&。如果您的文本不包括&那麼你不需要報價。

例如,如果文本只是「C:\我的音樂」,那麼你可以這樣做:

set myvar = c:\my music 

但是因爲你的文字有&您需要的報價。

編輯:

或者像戴夫在他回答說,你可以用^^^逃避問題的字符,但這種方法作爲&的提防是不是你需要的唯一字符逃逸。在實踐中,堅持引用而不是逃避所有問題字符要容易得多。

+0

這不是問題。問題在於引號與字符串的其餘部分一起存儲爲值的一部分。 這是字符串連接,字符串比較和許多其他事情的問題。 – GetFree 2009-02-11 09:12:53

+0

夠公平的,但如果你走的是逃跑的路線,那麼確保你知道所有需要逃跑的角色。 – andynormancx 2009-02-11 09:18:15

0

嘗試使用轉義字符'^',例如

set myvar=c:\my music ^& videos 

你有你的時候要小心展開MYVAR因爲shell可能不能治療&作爲文字。如果以上操作不起作用,請嘗試將插入符號插入字符串中:

set myvar=c:\my music ^^^& videos 
6

使用jscript。

很多天以前(即大約8年的時間)我正在研究一個大型的C++/VB6項目,並且我有各種各樣的批處理腳本來完成部分構建。

然後有人指我Joel Test,我特別喜歡第2點,並着手將我所有的小構建腳本合併到一個構建腳本中。 。 。它讓我幾乎傷了我的心,讓所有這些小腳本在不同的機器上一起工作,而且設置稍有不同,上帝讓它變得可怕 - 尤其是設置變量和參數傳遞。它非常脆弱,最輕微的事情會打破它,需要30分鐘的調整才能重新開始。

最後 - 我可以固執我 - 我在大約一天重新寫了這一切在JavaScript卡住了一大堆並,從cscript的命令提示符下運行它。

我還沒有回頭。儘管現在它是MSBuild和Cruise Control,但如果我需要做一些甚至與批處理腳本稍有關係的事情,我會使用jscript。

+2

這個問題並不是真正的答案,但是因爲我已經去過了cmd的la-la-land。EXE字符串轉義批處理文件內外,我完全同意你的看法。 +1 – Tomalak 2009-02-11 12:55:07

+2

不用說現在這些都是Powershell。 – 2014-10-10 08:09:49

+1

@BinaryWorrier精神,當然你會得到時間和使用假? (實際上並沒有開玩笑,這太棒了)(免責聲明:沒有100%確定你和/或OP正在討論構建腳本 - 只是在這裏以纏擾者爲基礎!) – 2014-10-24 11:57:20

34

這取決於你想如何使用變量。如果你只是想使用的變量的值,不包括引號,你可以使用延遲擴展和字符串替換,或for命令:

@echo OFF 
SETLOCAL enabledelayedexpansion 

set myvar="C:\my music & videos" 

由於andynormancx狀態,需要加引號,因爲該字符串包含& 。或者你可以用^來逃避它,但是我認爲這些報價有點乾淨。

如果您使用的字符串替換延遲擴展,你得到的變量的值不包括引號:

@echo !myvar:"=! 
>>> C:\my music & videos 

您還可以使用for命令:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P 
) 
>>> C:\my music & videos 

但是,如果想要在命令中使用該變量,必須使用引用的值或將變量的值用引號引起來:

  1. 使用字符串替換和延遲擴展使用沒有引號的變量的值,但是使用該變量的指令:

    @echo OFF 
    SETLOCAL enabledelayedexpansion 
    
    set myvar="C:\my music & videos" 
    md %myvar% 
    @echo !myvar:"=! created. 
    
  2. 使用for命令以使用沒有引號的變量的值,但你「會在命令中使用時,它用引號括變量:

    @echo OFF 
    set myvar="C:\my music & videos" 
    
    for /f "tokens=* delims=" %%P in (%myvar%) do (
        md "%%P" 
        @echo %%P created. 
    ) 
    

長話短說,沒什麼使用包含嵌入式SP的路徑或文件名中沒有乾淨的方式ace和/或&在批處理文件中。

+0

好的答案。謝謝。 – GetFree 2009-02-11 13:28:53

56

下的「變量名可以包含空格」這是正確的方式來做到這一點:

set "myvar=c:\my music & videos" 

的報價將不包括在該變量的值。

2

Windows命令解釋器允許您在整個set命令周圍使用引號(在NT 4的每個版本中都有效)。

@echo OFF 

set "myvar=C:\my music & videos" 

然後你可以將周圍的變量報價需要:0到Windows 2012 R2)

您的腳本應該只可以寫成。

使用CMD提示符有時看起來很深奧,但命令解釋程序在遵守它的內部邏輯時確實表現得相當穩固,您只需要重新考慮事情。

事實上,set命令根本不需要使用引號,但是您進行變量賦值的方式以及使用不引號的方法會導致變量周圍有額外的空格調試腳本時很難注意到這一點。

例如兩者的下方是技術上有效的,但你可以有尾隨空格,所以它不是一個好的做法:

set myvar=some text 
set myvar="some text" 

例如兩者的下面是在Windows命令解釋器設置變量好方法,但是雙引號的方法優於:

set "myvar=Some text" 
(set myvar=Some value) 

這些都留下任何的解釋變量會正是你正在尋找的數據。

強大的文本但是,你的目的,只是引述方法會有效,因爲你使用的是保留字符

這樣的工作,你可以使用:

set myvar="c:\my music & videos" 

然而,即使變量IS正確地設置爲這個字符串,當你使用ECHO時,命令解釋器將把&符號解釋爲關鍵字來表示另一個語句如下。

所以如果你想呼應自變量的CMD解釋仍然需要被告知這是一個文本字符串,或者如果你不想引號,以顯示你必須做下列之一的字符串:

回聲行情變量:

Echo."%myvar%" 

呼應變量不帶引號:

Echo.%myvar:&=^&% 
<nul SET /P="%myvar%" 

在上述兩種情況下,您可以重複使用沒有引號括起來的只是科幻東北。下面的示例輸出:

C:\Admin> Echo.%myvar:&=^&% 
C:\my music & videos 

C:\Admin> <nul SET /P="%myvar%" 
C:\my music & videos 
C:\Admin>