2015-10-07 79 views
1

我試圖創建一個程序,我通過文件(在一個文件夾及其所有子文件夾中)和動態替換部分行與其他部分。要做到這一點,我做了一個程序,但發現它的行爲出乎意料。字符串替換循環和遞歸意想不到的副作用

而不是隻是被替換的字符串,整條線被取代。然後我做了一些實驗,看到外面的循環替換字符串表現如預期,但在裏面......奇怪開始。

下面是一個非常基本的例子,在循環內部使用正常的字符串替換。

@echo off 
call :Rekursiv 
goto :eof 

:Rekursiv 
    set str=teh cat in teh hat 
    echo "Outside" 
    echo %str% 
    set str=%str:teh=the% 
    echo %str% 
    echo "Outside end" 

    for /D %%d in (*) do (
      cd %%~fd 

      set str=teh cat in teh hat 
      echo %str% 
      set str=%str:teh=the% 
      echo %str%  

      call :Rekursiv  

      cd.. 
    ) 

    exit /b  

現在通常我會想到:

teh cat in teh hat 
the cat in the hat 

和一些外,外端之間散落,但我得到的是:

"Outside" 
teh cat in teh hat  <--- as expected 
the cat in the hat  <--- as expected 
"Outside end" 
the cat in the hat  <--- Completely unexpected as its the replaced string already! 
the cat in the hat 
"Outside" 
teh cat in teh hat 
the cat in the hat 
"Outside end" 
the cat in the hat 
the cat in the hat 
"Outside" 
teh cat in teh hat 
the cat in the hat 
"Outside end" 
the cat in the hat 
the cat in the hat 
"Outside" 
teh cat in teh hat 
the cat in the hat 
"Outside end" 

環路外的所有置換工作因爲我認爲他們應該。但是在循環內部,看起來這些集合都是在回聲完成之前完成的。因爲我認爲這和我的換線問題有相同的來源/原因我的問題在這裏:爲什麼程序產生這個意外的輸出?我能做些什麼來獲得預期的產出?

編輯:MCDNs評論後,我試過的事情了:

@echo off 
call :Rekursiv 
goto :eof 

:Rekursiv 
    set str=teh cat in teh hat 
    echo "Outside" 
    echo %str% 
    set str=%str:teh=the% 
    echo %str% 
    echo "Outside end" 


set "test=before" 
if defined test (
    set "test=after" 
    echo %test% 
) 

    for /D %%d in (*) do (
      cd %%~fd 

      set str=teh cat in teh hat 
      echo %str% 
      set str=%str:teh=the% 
      echo %str%  

set "test=before" 
if defined test (
    set "test=after" 
    echo %test% 
) 

      call :Rekursiv  

      cd.. 
    ) 

的「回聲%測試%」第一次出現是「前」,二是「後」

+0

也許[這](http://stackoverflow.com/a/30177832/ 2861476)可以幫助 –

+0

@MCND嗯有趣的一點。在一個循環之外,我明白了。但在循環內部它是「之後」,你知道爲什麼嗎? (「之前」我會期望,因爲它是在循環外部相同,但我在循環內部後)。時刻將更新那裏的解決方案。 – Thomas

+0

啊,也許我理解它。是否可以這樣:第一次發生在那之前,如果設置生效,因此第二次回波被設置爲在這之後? (因爲它在查看「test = before」之前解析了第二個%測試%)? – Thomas

回答

0

短:百分比擴張在塊之前完成,將在解析時執行。

在任何內部執行之前,您都可以看到具有固定字符串的塊。

因此,延遲擴展存在,這是執行單個命令時評估。
語法幾乎相同,但使用百分號而不是感嘆號。
但在此之前,你可以使用延遲擴展,它必須與

setlocal EnableDelayedExpansion 

啓用所以,你的代碼看起來像

@echo off 
setlocal EnableDelayedExpansion 
call :Rekursiv 
goto :eof 

:Rekursiv 
    set str=teh cat in teh hat 
    echo "Outside" 
    echo %str% 
    set str=%str:teh=the% 
    echo %str% 
    echo "Outside end" 

    for /D %%d in (*) do (
      cd %%~fd 

      set "str=teh cat in teh hat" 
      echo !str! 
      set str=!str:teh=the! 
      echo !str! 
    )