So the situation is like so... I have two nested if statements and then a loop inside them (using the GoTo command and an incremented variable - for loop simulation :D). As you probably know to assign new values to variables inside of parentheses (of an if statement) you have to use delayedexpansion. Also to use variables in the for command you have to double the percent marks like so %%. I want to set the tokens in a for /f command to be the value of the variables I'd like. The problem is doubling the exclamation marks has no effect. I also tried all sorts ... like using quotes, escaping those quotes, using quote alternatives, but it was all to no avail. If you can help in any way that would be just great, because I can't think of anything at all :(. Thank you in advance guys!
If that made no sense here's the code:
@echo off
set FilePath=test.bat
set RefreshRate=3
setlocal enabledelayedexpansion enableextensions
:GetData
if defined FilePath (
if exist "%FilePath%" (
:GetLines
cls
:: This is how I find out how many lines there is in the file
set "cmd=findstr /R /N "^^" "%FilePath%" | find /C ":""
for /f %%a in ('!cmd!') do set Lines=%%a
:ShowCode
cls
set LineNum+=1
if ""!LineNum!"" GTR ""!Lines!"" GoTo Refresh
::THIS IS THE MAIN PROBLEM
for /f "tokens=%%LineNum%% delims=$" %%b in ("%FilePath%") do (
set Line%LineNum%=%%b
echo !LineNum!. | !Line%LineNum%!
GoTo ShowCode
)
)
)
:Refresh
ping localhost -n %RefreshRate% >nul
GoTo GetData
I'm sorry that I didn't have enough time to make it more readable, but it should make the whole thing a little clearer.
First: use neither :: remark
comments nor :label
in a code block enclosed in ()
parentheses. A proof of harmfulness you could find in the labels.bat
script encoded in output from a script provided thereinafter; an explanation here: Comments within bracketed code blocks.
In next script, non-empty lines of a particular plain text file (cf. set "FilePath=labels.bat"
) are saved to a pseudo-array LineAAA
, where index AAA
= line number. I do not know whether it isn't off topic according to your question but could give some useful clue...
@echo off
setlocal enabledelayedexpansion enableextensions
cls
set line
set "FilePath=labels.bat"
set /A "RefreshRate=3"
:GetData
if not defined FilePath (
echo %%FilePath%% not defined
goto :eof
)
if not exist "%FilePath%" (
echo %FilePath% does not exist
goto :eof
rem following 'else' (sub)statement seems to be superabundant
) else (
rem GetLines
rem This is how I find out how many lines there is in the file
set "cmd=findstr /R /N "^^" "%FilePath%" | find /C ":""
for /f %%a in ('!cmd!') do set /A "Lines=%%a"
set /A "LineNum=0"
set "Line000=@rem %FilePath%"
for /f "tokens=*" %%b in (%FilePath%) do (
set /A "LineNum+=1"
set "LineX=000000000!LineNum!"
set "LineX=!LineX:~-3!"
set "Line!LineX!=%%b"
)
call :Refresh
)
set line
rem pause
endlocal
goto :eof
:Refresh
ping localhost -n %RefreshRate% | findstr /I "Packets: statistics"
rem >nul
GoTo :eof
Output:
Environment variable line not defined
Ping statistics for ::1:
Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Line000=@rem labels.bat
Line001=@SETLOCAL enableextensions enabledelayedexpansion
Line002=@ECHO ON >NUL
Line003=if ""=="" (
Line004=rem comment
Line005=@echo rem comment
Line006=)
Line007=if ""=="" (
Line008=:: comment
Line009=@echo :: comment
Line010=)
Line011=if ""=="" (
Line012=:label
Line013=@echo :label
Line014=)
Line015=@ENDLOCAL
Line016=@goto :eof
LineNum=16
Lines=16
LineX=016
labels.bat output:
d:\bat>labels.bat
d:\bat>if "" == "" (
rem comment
)
rem comment
d:\bat>if "" == "" (@echo :: comment )
'@echo' is not recognized as an internal or external command,
operable program or batch file.
d:\bat>if "" == "" (@echo :label )
'@echo' is not recognized as an internal or external command,
operable program or batch file.
d:\bat>