2014-01-25 26 views
3

我不知道有沒有什麼辦法來檢查,如果一個標籤在批處理文件中存在嗎?檢查CMD

If %input%=ABC ( 
    If Label ABC Exists (
    Goto ABC 
) 
) 

我該怎麼做? 任何幫助將不勝感激。

回答

8
findstr /i /r /c:"^[ ]*:%input%\>" "%~f0" >nul 2>nul && goto %input% 

搜索標籤,在當前的批處理文件,如果沒有錯誤級別,標籤存在

編輯 - 我意識到是在我被處理的結束標籤的方式錯誤,並打算編輯答案(它已被編輯),我看到了dbenham aclarations。他看到了錯誤並糾正了錯誤。謝謝。好的回答一如既往,但這比你所暴露的更糟糕。

在這一刻我只有XP測試,但這是我的作品。如果有人可以在以後的Windows版本上測試,請。

第一個問題:標籤的開始。像往常一樣,dbenham是正確的,並且集合[;=,<space><tab>0xFF]中的任何字符都可以在標籤的冒號前面,單個或重複。但是,只要它是行中的第一個字符,並且不重複,幾乎任何字符都可以在標籤的冒號之前(一個例外是其他冒號)。所以,下面的工作沒有任何問題

call :test 
    goto :test 
    echo this will not be echoed 

X=;=:test 
    echo Hello 

NO,這難道不是一種有效的線,如果解析器嘗試執行標籤行,會發生錯誤「無法識別的命令」,但是一個有效的標籤來電或轉到。

問題二:標籤的結束。正如dbenham所指出的,當標籤用於定義一個函數/過程時,我們大多數人都會放置一個空格和參數列表。這是我意識到的錯誤,以及我原來的答案中已更正的錯誤。但是,一個空格(顯然是行尾)不是標籤名稱後面的唯一允許的字符。所以,在前面的示例,下列任何標籤將工作

:test arguments 
:test:arguments 
:test>arguments 
:test<arguments 
:test&arguments 

是的,在這種情況下,它們對解析器有效的命令和有效的標籤

,當然,這兩個「問題「可以同時發生

call :test 
    goto :test 
    echo this will not be echoed 

<;;:test:;;> This WORKS 
    echo Hello 

POST編輯1 - 似乎所有這些工作都是在dostips.com幾年前完成的。感謝所有編寫評論中引用的詳細列表的人。下一次,我會先搜索。

POST編輯2 - 我一直在試圖解決FINDSTR的限制,包括所有的情況。那麼,沒有辦法。有太多的限制,從不可能在正則表達式中包含0xff字符開始。

一個強大而簡單的解決方案,從dbenham答案是最好的選擇。

對於更強勁,但仍不完整,沒有防彈版本,比dbenham的回答

@echo off 

    for /l %%i in (1 1 10) do (
     call :testLabelExist "test%%i" && echo Label [test%%i] exist || echo Label [test%%i] does not exist 
    ) 
    exit /b 

:test1 
:test2 
    :test3 
x:test4 
::test5 
:test6: 
:test7# 
:test8 parameters 
    :test9 parameters 
:test10:myData 


:testLabelExist 
    for /f "delims=" %%t in (
     'forfiles /p "%~dp0." /m "%~nx0" /c "cmd /d /c @echo 0x09"' 
    ) do (
     findstr /i /m /r /c:"^[^:]*[ %%t]*:%~1[ %%t:;,=+]" /c:"^[^:]*[ %%t]*:%~1$" "%~f0" >nul 2>nul 
    ) 
    exit /b %errorlevel% 

它仍然遺漏了引號標籤名稱更復雜,僅舉一個故障點。

+0

這是工作,但我希望下一次會有解釋。輝煌! – Jamie

+0

+1,但我在[我的回答](http://stackoverflow.com/a/21352240/1012053)中添加了一些改進 – dbenham

+2

使用字邊界詞的好主意,但在這種情況下效果不佳。 FINDSTR認爲非字詞字符的許多字符在標籤內有效。一個例子是'#'。例如,':label#'是一個有效的標籤,並且您的搜索將錯誤地匹配'label',而沒有尾隨'#',因此在GOTO失敗時會導致致命錯誤。所有其他的觀點都是有效的 - 實際的解決方案是忽略它們。不要在你的腳本中使用奇怪的標籤:-) – dbenham

6

這裏是MC ND answer的一個精煉的,更強大的版本。

標籤不區分大小寫,因此搜索應該不區分大小寫。

有效的標籤可能在標籤後面有附加文本,因此需要進行兩次搜索。附加文本經常用作文檔。例如::label documentation仍然是有效的標籤。

findstr /ri /c:"^ *:%input% " /c:"^ *:%input%$" "%~f0" >nul 2>nul && goto %input% 

上面應該在大多數情況下工作,但有一些不太可能導致它失敗的條件。

任何以下字符可以在標籤之前出現 - ,;=<space><tab><0x255>。它們在標籤之前都被當作空格。

該標籤可能包含正則表達式元字符。

可以對搜索進行細化以處理上述兩個條件。但在代碼中簡單地避免這些條件會更簡單。

+0

+1,我不應該這麼快回答。謝謝。你能看到我更新的答案和測試其他版本,我看到我的XP? –

2

試試下面的代碼:

echo off 
set "label=sub" 
REM next line to reset errorlevel to zero: 
(call) 
call :%label% 2>nul || (echo %label% not found & exit /b 1) 
echo back from %label% 
Exit /b 0 

:sab 
echo here we are