2011-01-05 21 views
6

Próbuję utworzyć ogólny plik wsadowy, który może informować o błędach z numerem wiersza, w którym wystąpił błąd.
Ale pisanie każdego numeru linii w kodzie jest trochę denerwujące.Jak uzyskać numer bieżącej linii?

Czy można uzyskać aktualny numer linii, gdy uruchomiony jest plik wsadowy?
Aby poniższy kod działał?

@echo off 
call :doSomething 1 

if %errorlevel% GTR 0 (
    REM Do something magic, to retrieve the lineNo 
    call :getCurrentLineNo currentLineNo 
    echo Error near %currentLineNo% 
) 

call :doSomething 2 

if %errorlevel% GTR 0 (
    call :getCurrentLineNo currentLineNo 
    echo Error near %currentLineNo% 
) 

Odpowiedz

16

Zawsze jest sposób ...
Nie znaleźliśmy idealne rozwiązanie, ale dobre obejście mogę użyć.

Wywołuję funkcję, która przeszukuje własny plik wsadowy (%~f0) za pomocą findStr, dla parametru funkcji <uniqueID>, więc działa tylko wtedy, gdy te <uniqueID> są naprawdę unikalne dla całej partii.
Lniany jest uzyskiwany z wyniku findstr /N.

W tej próbki:
6: call :getLineNumber errLine uniqueID4711 -2

Trzeci parametr -2 służy do dodawania przesunięcia do LineNumber, więc wynik będzie 4.

@echo off 
SETLOCAL EnableDelayedExpansion 

dir ... > nul 2> nul 
if %errorlevel% NEQ 0 (
    call :getLineNumber errLine uniqueID4711 -2 
    echo ERROR: in line !errLine! 
) 

set /a n=0xGH 2> nul 
if %errorlevel% NEQ 0 (
    call :getLineNumber errLine uniqueID4712 -2 
    echo ERROR: in line !errLine! 
) 
goto :eof 

::::::::::::::::::::::::::::::::::::::::::::: 
:GetLineNumber <resultVar> <uniqueID> [LineOffset] 
:: Detects the line number of the caller, the uniqueID have to be unique in the batch file 
:: The lineno is return in the variable <resultVar> add with the [LineOffset] 
SETLOCAL 
for /F " usebackq tokens=1 delims=:" %%L IN (`findstr /N "%~2" "%~f0"`) DO set /a lineNr=%~3 + %%L 
( 
    ENDLOCAL 
    set "%~1=%LineNr%" 
    goto :eof 
) 
+4

+1, Jeb Cześć, Właśnie zauważyłem ten post, bardzo fajne :-) Prawdopodobnie powinien zmienić swoje wyszukiwanie findstr do użycia '/ n/c: "% 2"' ~ (miejsca po obu stronach ID) z konwencją, że identyfikatory nigdy nie zawierają miejsca. Nie chcesz, aby "abc123" pasowało do "zabc1234". Opcja/C zapobiega również interpretowaniu czegoś takiego jak "A.1" jako wyrażenie regularne. Ponadto identyfikatory nie powinny zawierać ukośnika odwrotnego, aby uniknąć problemów z wylogowaniem z FINDSTR, ani wyszukiwać i zamieniać \ z \\ w kodzie. – dbenham