2015-06-14 67 views
2

我試圖刪除變量中的字符!批量替換!-sign

setlocal enableextensions enabledelayedexpansion 
set filename=!filename:!=_! 

我已經試圖用^來逃避它,但這沒有奏效。

Set filename=!filename:^!=_! 

我該如何擺脫變量中的!-sign?

+0

是循環的一部分還是條件?不能禁用延遲擴展嗎? – npocmaka

+0

是的,它是一個循環的一部分。需要延遲擴展。 – ozz

+0

你可以顯示你的循環和文件名是_produced_ – jeb

回答

2

的是,目前在我的腦海裏彈出的僅是子程序和隧道:

@echo off 

set "line=!---!asd!asd!" 

setlocal enableDelayedExpansion 
    echo !line! 
    call :subr "!line!" line 
    echo !line! 
endlocal 
exit /b %errorlevel% 

:subr 
setlocal disableDelayedExpansion 
    set "string=%~1" 
    set "res=%string:!=$%" 
endlocal && (
    set "%~2=%res%" 
) 

只要定義子程序像這樣在你的腳本結束,並調用它在for循環

+0

我不明白子程序的目的。 'set「line =%line:!= $%」'同時啓用延遲擴展也可以工作,並且它非常簡單。即使您想暫時禁用延遲擴展,也不需要涉及子程序。但禁用延遲擴展是完全沒有必要的。 – dbenham

+0

@dbenham - OP說這是FOR循環的一部分 - 所以這行不會在這種情況下工作。這是一個演示如何使用子例程 - 因爲整個代碼塊沒有發佈,我需要我自己的例子。 – npocmaka

+0

哦,快點。我錯過了評論。你是完全正確的 - 需要一個CALL。 – dbenham

4

使用正常擴展時,不能替換%。您必須使用延遲擴展:!var:%%=_!

同樣,使用延遲擴展時不能替換!。您必須使用正常擴展:%var:!=_%

但是,這可能是一個問題,如果你的變量可能含有的毒字符的組合,像^&|><以及報價。例如,在以下字符串中沒有單一步驟來替換!"This & that" & the other thing!

訣竅在於使用大多數延遲擴展進行替換,使用正常擴展進行一次替換。

1)延遲擴展 - 轉換成"""

2)正常膨脹 - 轉換成!replacement。由於股價翻番,圍繞擴張外報價現在保證保護所有毒藥字符

3)延遲擴張 - 轉換"""

@echo off 
setlocal enableDelayedExpansion 
set "var="This ^& that" & the other thing^!" 
echo before: !var! 

set "var=!var:"=""!" 
set "var=%var:!=_%" 
set "var=!var:""="!" 

echo after: !var! 

- 輸出 -

before: "This & that" & the other thing! 
after: "This & that" & the other thing_ 

但是你正在處理文件名,這可以使問題變得更簡單:-)

文件名可以con毒害字符&^,但它們不能包含引號。您可以將引號放在文件名(或路徑)中的任何位置,並且它們將保護有毒字符。但是,當操作系統存儲或查找磁盤上的文件時,引號將被刪除。

所以我通常確保我的文件名和路徑變量不包含引號。然後,它是安全的,簡單地使用:

set "filename=%filename:!=_%" 

哎呀 - 我現在纔讀的問題的意見,看看這是一個循環中!

替換髮生在循環內的事實使事情複雜化,因爲正常的擴展將不會看到在循環內定義的值。

請注意,擴展FOR變量時必須關閉延遲擴展,否則會在文件名中破壞!

最簡單的解決方案是使用CALL來獲得額外的一輪擴張:如果你是這樣做需要延遲擴展其他操作

@echo off 
setlocal disableDelayedExpansion 
for %%F in (*) do (
    set "file=%%F" 
    call set "file=%%file:!=_%%" 
    setlocal enableDelayedExpansion 
    echo file=!file! 
    endlocal 
) 

,那麼!將需要在正常的膨脹更換內逃脫表達式,因爲延遲擴展發生在CALL之前。 (謝謝jeb)。

下面是一個例子,它也消除了^&

@echo off 
setlocal disableDelayedExpansion 
for %%F in (*) do (
    set "file=%%F" 
    setlocal enableDelayedExpansion 
    set "file=!file:^=_!" 
    set "file=!file:&= and !" 
    call set "file=%%file:^!=_%%" 
    echo file=!file! 
    endlocal 
) 

雖然我可以方便地實現後延遲擴展我已經刪除!。那麼逃跑就不需要了。

+2

一些建設性的批評:'調用集「文件= %%文件:!= _ %%」 '在你的示例中不起作用,因爲在擴展百分比完成之前'!'將被刪除,所以百分比擴展失敗,因爲'%file:= _%'無效。你**不需要**子程序,因爲CALL階段從不會看到任何插入符號。解決方案是'call set'file = %% file:^!= _ %%「 – jeb

+0

@jeb - 謝謝jeb--你們兩個都是正確的(當然)。我忘記了逃避問題(顯然沒有測試),並沒有認爲插入符號正確地翻倍。我編輯了我的答案以解決您的觀點。 – dbenham