分析文本文件中的数据的批处理文件出现问题

问题描述 投票:0回答:1

我有一些代码正在逐行读取文本文件并对其进行一些分析。

循环检查每行是否以数字开头,如果以数字开头,则需要验证该行上某个位置的信息。

这部分如果工作的话。

但是我还需要检查最后一行是否有一个条目“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 语句来帮助我调试。

如有任何帮助,我们将不胜感激。

batch-file
1个回答
0
投票

您做出的关键断言是

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%"
的值。

© www.soinside.com 2019 - 2024. All rights reserved.