我有一些代码正在逐行读取文本文件并对其进行一些分析。
循环检查每行是否以数字开头,如果以数字开头,则需要验证该行上某个位置的信息。
这部分如果工作的话。
但是我还需要检查最后一行是否有一个条目“END” - 如果它有一个 END 就可以了,但如果没有,它应该提供一条错误消息。
数据如下:
VOL1FirstLine
HeaderLine1
HeaderLine2 00
Uline
1212314214152156182651265172651782658172561651SAMPLETEXTTOCHECKNumbersadada adafaafaf
1212314214152156182651265172651782658172561651SAMPLETEXTTOCHECKNumbersadada adafaafaf
4125151514214152156182651265172651782658172561SAMPLETEXTTOCHECKNumbersadada adafaafaf
1312442141431421415215618265126517265178265817SAMPLETEXTTOCHECKNumbersadada adafaafaf
1312442141431421415215618265126517265178265817SAMPLETEXTTOCHECKNumbersadada adafaafaf
4125151514214152156182651265172651782658172561SAMPLETEXTTOCHECKNumbersadada adafaafaf
4125151514214152156182651265172651782658172561SAMPLETEXTTOCHECKNumbersadada adafaafaf
4125151514214152156182651265172651782658172561SAMPLETEXTTOFailSNumbersadada adafaafaf
41251515142141521561826512651726517826581725616SAMPLETEXTTOCHECKNumbersadada adafaafaf
4125151514214152156182651265172651782658172561SAMPLETEXTTOCHECKNumbersadada adafaafaf
EOF121412415152
EOF214125151514
UTL
END
因此 SAMPLETEXTTOFail 行应该失败,并且工作正常。但我无法让我的代码检查最后一行。
代码如下:
@echo off
SETLOCAL DisableDelayedExpansion
REM hard coded for now - this is the value i want to check against
set "NewName=SAMPLETEXTTOCHECKN"
echo %NewName%
pause
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ D:\sample.TXT"`) do (
set "myVar=%%a"
call :processLine myVar
)
goto :eof
:processLine
SETLOCAL EnableDelayedExpansion
set "line=!%1!"
set "line=!line:*:=!"
echo(!line!
Rem get first three characters for testing End is present on last row
set "ThreeChar=%Line:~0,3%"
Echo %ThreeChar%
Rem get first character to check if a number as data rows to check start with a number
set "FirstChar=%Line:~0,1%"
Echo %FirstChar%
Rem check if first character is a number
SET "var="&for /f "delims=0123456789" %%i in ("%FirstChar%") do set var=%%i
if defined var (echo %FirstChar% NOT numeric) else (echo %FirstChar% numeric)
rem if numeric read in
SET "var="&for /f "delims=0123456789" %%i in ("%FirstChar%") do set var=%%i
rem if numeric then read in variable
if not defined var set "SchemeTest=%Line:~46,18%"
REM Test against expected value
echo %SchemeTest%
REM this line below not yet tested
REM if NOT "%SchemeTest%" == "%NewName%" echo ERROR: This file appears to hold unexpected data, please review. & goto ErrorExit
REM REMOVE ERROR EXIT FOR NOW
if not defined var if NOT "%SchemeTest%" == "%NewName%" echo ERROR: This file appears to hold data for more than one client, please review.
PAUSE
rem commented out as never seems to run
echo should be out of the loop here
rem last entry should be end
REM if NOT "%ThreeChar%" == "END" echo ERROR: This file appears to have no End row, please review. & goto ErrorExit
REM REMOVE ERROR EXIT FOR NOW
if NOT "%ThreeChar%" == "END" echo ERROR: This file appears to have no End row, please review.
ENDLOCAL
goto :eof
PAUSE
我认为问题在于我把这些行放在哪里:
rem commented out as never seems to run
echo should be out of the loop here
rem last entry should be end
REM if NOT "%ThreeChar%" == "END" echo ERROR: This file appears to have no End row, please review. & goto ErrorExit
REM REMOVE ERROR EXIT FOR NOW
if NOT "%ThreeChar%" == "END" echo ERROR: This file appears to have no End row, please review.
如果我把它们放在 ENDLOCAL goto :eof 之后,它们就不会运行。如果我把它们放在 ENDLOCAL goto :eof 之前,它们会为每一行运行。
我不需要在每一行上运行这段代码,我只需要在读入的最后一行上运行它。我在想,如果我在循环完成后这样做,这将作为变量工作%twochar% 应该仍然具有最终通过循环的值。
我知道 EOF 退出子例程并且 endlocal 重置变量。所以这需要在循环之后和本地结束之前发生。我尝试过代码和 EOF、ENDLOCAL 的各种组合和放置,但目前我只能让它每次运行或根本不运行。
我的代码有很多回显和暂停,因此我可以逐行看到发生了什么。还有各种 rem 语句来帮助我调试。
如有任何帮助,我们将不胜感激。
您做出的关键断言是
the variable %threechar% should still have the value of the final pass through the loop.
嗯,确实如此,当执行
endlocal
或 goto :eof
时,但 endlocal
将环境恢复到 setlocal
时的状态。
允许跨越
endlocal
屏障维护变量的经典方法是一段明显奇怪的代码
endlocal&set "threechar=%threechar%"
检查逻辑代码行有效性的解析器将其翻译为
endlocal&set "threechar=<the current value of threechar>"
然后是两个命令
endlocal
set "threechar=<the current value of threechar>"
被执行,其中
<the current value of threechar>
是遇到行 threechar
时 endlocal&set "threechar=%threechar%"
的值。