Windows batch For Loop dropping empty strings to the end - windows

I have this following code.
#echo off
setlocal EnableDelayedExpansion
set holdingline=,Measure,,+ X,,,0,0
FOR /F "tokens=1,2,3,4,5,6,7,8 delims=," %%a IN ("%holdingline%") DO (
echo %%a
echo %%b
echo %%c
echo %%d
echo %%e
echo %%f
echo %%g
echo %%h
echo %holdingline%
)
pause
Output displayed is as below:
Measure
+ X
0
0
ECHO is off.
ECHO is off.
ECHO is off.
ECHO is off.
,Measure,,+ X,,,0,0
The empty strings are pushed to the end and I wonder why. I am expecting them in order, say something like:
ECHO is off.
Measure
ECHO is off.
+ X
ECHO is off.
ECHO is off.
0
0
,Measure,,+ X,,,0,0
This would enable me to assign them to the correct variables. I tried searching but did not find much help.

#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set holdingline=,Measure,,+ X,,,0,0
FOR /F "tokens=1-8 delims=," %%a IN (""%holdingline:,=","%"") DO (
ECHO(%%~a
ECHO(%%~b
ECHO(%%~c
ECHO(%%~d
ECHO(%%~e
ECHO(%%~f
ECHO(%%~g
ECHO(%%~h
echo %holdingline%
)
GOTO :EOF
This should solve your problem
To process a file, producing a new file
#ECHO OFF
SETLOCAL
(
FOR /f "delims=" %%x IN (q29639243.txt) DO (
set "holdingline=%%x"
CALL :process
)
)>u:\new.txt
GOTO :EOF
:process
FOR /F "tokens=1-8 delims=," %%a IN (""%holdingline:,=","%"") DO (
ECHO(%%~a
ECHO(%%~b
ECHO(%%~c
ECHO(%%~d
ECHO(%%~e
ECHO(%%~f
ECHO(%%~g
ECHO(%%~h
echo %holdingline%
)
GOTO :EOF
I used a file named q29639243.txt containing similar data for my testing.
Produces u:\new.txt

This should do what you want it to:
#echo off
setlocal EnableDelayedExpansion
set holdingline=,Measure,,+ X,,,0,0
FOR /F "tokens=1,2,3,4,5,6,7,8 delims=," %%a IN ("%holdingline:,,=, ,%") DO (
echo %%a
echo %%b
echo %%c
echo %%d
echo %%e
echo %%f
echo %%g
echo %%h
echo %holdingline%
)
pause
Replacing ,, with , , will cause it to set the middle variables to (space) and hence treat them like nothing. If you don't have anything between two , it will skip them and hence only 4 variables exist, leaving e-h blank

Related

Getting delayed expansion value to function output

Here is a windows cmd fragment:
:moveFiles
#for /f %%R in ('dir /b current') do (
#echo ___
#echo Moving %%R to FTP server.
%java_cmd% -jar f17ftp.jar -dput -file:%%R %select%
if 1 neq 0 (
#echo Transfer of %%R failed.
call :readLog
echo %log%
%java_cmd% -cp SQLQueryXML.jar com.saliencrgt.chums.AlertMessage "Contents of ftp log are:<br/><br>"%log%
) else (
#echo Transfer of %%R succeeded.
move current\%%R xmlfiles 1> nul
)
)
exit /b
:readLog
setlocal enableextensions enabledelayedexpansion
#for /F "delims=" %%x in (f17ftp.debug.log) do (
if .!build!==. (set build=%%x) else (set build=!build!,%%x)
)
endlocal & set log=!build!
exit /b
I am trying to get the contents of a file into a variable to send as an argument to a java class
The readLog function does read the file and if I echo !build! prior to the endlocal the file contents do print to the console.
I can set "log" to a constant instead of the !build! variable and I see it in the calling function, but I can't get the delayed variable value out of the function.
Here's a quick example of how I'd expect your :readLog labelled section to look:
:readLog
#set "log="
#setlocal enableextensions enabledelayedexpansion
#set "build="
#for /f "usebackq delims=" %%x in ("f17ftp.debug.log") do #(
if not defined build (set "build=%%x") else set "build=!build!,%%x"
)
#endlocal & set "log=%build%"
#exit /b
However to view it, as it is still being defined within a parenthesized block, you will probably find that your :moveFiles labelled section would also need to have enabled delayed expansion, and then echo !log! not echo %log%.
You may find therefore that something a little more like this will work better for you:
:moveFiles
#for /f "eol=? delims=" %%R in ('dir /b "current" 2^>nul') do #(
echo ___
echo Moving %%R to FTP server.
"%java_cmd%" -jar "f17ftp.jar" -dput -file:"%%R" %select%
if errorlevel 1 (
echo Transfer of %%R failed.
setlocal enabledelayedexpansion
set "log="
set "build="
call :readLog
echo !log!
"%java_cmd%" -cp "SQLQueryXML.jar" com.saliencrgt.chums.AlertMessage "Contents of ftp log are:<br/><br>"!log!
endlocal
) else (
echo Transfer of %%R succeeded.
move "current\%%R" "xmlfiles" 1>nul
)
)
#exit /b
:readLog
#for /f "usebackq delims=" %%x in ("f17ftp.debug.log") do #(
if not defined build (set "build=%%x") else set "build=!build!,%%x"
)
#set "log=%build%"
#exit /b

CMD script: variable not correctly evaluated in a "for" loop

I made a cmd script to get the freespace of each drive in a PC and send an alert if under a value (the constant "MyLimit").
I found that the variables are not correctly evaluated in my "for" loop (the cycle within the list of drives)
This is the "for" loop:
Set MyLimit=107374182400
for /f "tokens=1-3" %%a in ('WMIC LOGICALDISK GET FreeSpace^,Name^,Size ^|FINDSTR /I /V "Name"') do (
if not "%%c"=="" (
echo FreeSpace=%%a
echo Name=%%b
echo Size=%%c
if %%a LSS %MyLimit% (
Echo not enough free space in %%b
) else (
echo "do nothing"
)
)
)
but the variable %%a always assumes the value of the last index of the "for" loop...
then the IF always fails...
Where is the error?
Thanks for your support
Ale
I tried your suggestions, see below, but still it doesn't work maybe I put some error inside the code, I'm not so sure to have well done:
#Echo off
SETLOCAL enabledelayedexpansion
Set GB100=107374182400
Set TB_10=10995116277760
Set MyLimit=%TB_10%
for /f "tokens=1-3" %%a in ('WMIC LOGICALDISK GET FreeSpace^,Name^,Size ^|FINDSTR /I /V "Name"') do (
if not "%%c"=="" (
echo FreeSpace=%%a
echo Name=%%b
echo Size=%%c
call :padNum %%a
call :padNum MyLimit
echo %%a
echo %MyLimit%
if "%%a" LSS "%MyLimit%" (
Echo not enough free space in %%b
) else (
echo "nothing"
)
)
)
:padNum
setlocal enableDelayedExpansion
set "n=000000000000000!%~1!"
set "n=!n:~-15!"
endlocal & set "%~1=%n%"
exit /b
I intentionally put a high limit (10TB) to force the message...
Just a little issue in your code: the metavariable %%a doesn't behave like normal %environmentVariables%, so you can't use them alike.
#Echo off
SETLOCAL enabledelayedexpansion
Set GB100=107374182400
Set TB_10=10995116277760
Set MyLimit=%TB_10%
for /f "tokens=1-3" %%a in ('WMIC LOGICALDISK GET FreeSpace^,Name^,Size ^|FINDSTR /I /V "Name"') do (
if not "%%c"=="" (
echo FreeSpace=%%a
echo Name=%%b
echo Size=%%c
set free=%%a
call :padNum free
call :padNum MyLimit
echo free= !free!
echo MyLimit= !MyLimit!
if "!free!" LSS "!MyLimit!" (
Echo not enough free space in %%b
) else (
echo "nothing"
)
)
)
goto :eof
:padNum
setlocal enableDelayedExpansion
set "n=000000000000000000!%~1!"
set "n=!n:~-18!"
endlocal & set "%~1=%n%"
exit /b
(and I took the freedom to expand from 15 to 18 chars, so you won't have trouble in the near future, when disks get bigger.)

How to escape ! in a variable's value?

How may I escape embedded ! characters in the value of a variable PL used in delayed expansion !PL!, such that they are not interpreted as delimiters?
E.g. to remedy the failure of this when %%P contains ! .
FOR %%P IN (%input%\*.M3U) DO (
echo Processing playlist "%%P"
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=*" %%L IN ('type "%%P"') DO (
SET PL=%%~pP%%L
echo Processing reference "!PL!"
)
ENDLOCAL
)
EDIT: Paul's limited-applicability workaround:
FOR %%P IN (%input%\*.M3U) DO (
echo Processing playlist "%%P"
FOR /F "tokens=*" %%L IN ('type "%%P"') DO (
SET PL=%%~pP%%L
SETLOCAL ENABLEDELAYEDEXPANSION
echo Processing reference "!PL!"
ENDLOCAL
)
)
I don't know how you can search/replace a ! inside a !var! (!myvar:^^!=!! doesn't work) but you can display ! in var like:
#echo off
(
echo !!myfolder
echo myfi!es
echo !234
)>sample.txt
for /f %%a in (sample.txt) do (
set "myvar=%%a"
setlocal enabledelayedexpansion
echo !myvar!
endlocal
)
You can transpose on your code like this:
for %%p in (%input%\*.m3u) do (
echo processing playlist "%%p"
for /f "tokens=*" %%l in ('type "%%p"') do (
set pl=%%~pp%%l
setlocal enabledelayedexpansion
echo processing reference "!pl!"
endlocal
)
)

nested for loops with variable used in the nested loop windows batch

I have a first loop and a second loop but the variable from the first loop always stays the same in the second loop. how do i get the actual value of the second loop?
REM #echo off
set fastestserver=none
set fastestresponse=99999999ms
for /F "tokens=*" %%A in (fileservers.txt) do (
for /F "skip=8 tokens=9 delims= " %%B in ('ping -n 3 %%A') do (
echo %%A
echo %%B
set fastestresponse=%%B
set actualpingserver=%%B
if /I "%fastestresponse:~,-2%" GTR "%actualpingserver:~,-2%" (
set fastestresponse=%%B
set fastestserver=%%A
)
)
)
REM #echo on
echo %fastestserver%
echo %fastestresponse%
in the fileserver.txt there are some servers inside, each get pinged and i want to get the average ping, if the ping is smaller then of the one before it should replace the 2 variables (fastestserver , fastestresponse ).
Problem now is that if i debug the script it always takes for
if /I "%fastestresponse:~,-2%" LSS "%actualpingserver:~,-2%"
so somehow from the second for the fastestresponse does not get filld because the value is always 999999999ms.
Thanks already for a hint/helping answer
try this:
REM #echo off
setlocal enableDelayedExpansion
set fastestserver=none
set fastestresponse=99999999ms
for /F "tokens=*" %%A in (fileservers.txt) do (
for /F "skip=8 tokens=9 delims= " %%B in ('ping -n 3 %%A') do (
echo %%A
echo %%B
set actualpingserver=%%B
if /I "!fastestresponse:~,-2!" GTR "!actualpingserver:~,-2!" (
set fastestresponse=%%B
set fastestserver=%%A
)
)
)
REM #echo on
echo %fastestserver%
echo %fastestresponse%
endlocal
more info about delayed expansion

Windows batch Nested for loop issue

I need to read a file in outer loop line by line, take this value and use it in inner loop. But currently I am able to read first line from this file and do some required processing in inner loop but outer loop runs only once.
Why does the outer loop run only once?
myfile.txt contains:
AWC00201
AWC00202
AWC00203
DDDD
#echo off
setlocal EnableDelayedExpansion
for /F %%D in (myfile.txt) do (
echo %D%
S:
cd \#vantage\AFG\AWC\AWCU\simulation\WRO_Regression_results\%%D
echo %%D
FOR /F %%i IN ('dir /b /ad-h /o-d') DO (
echo After Nested For
echo %%D
SET test=%%D
SET b=%%i
GOTO found
)
echo No subfolder found
goto done
:found
echo %D%
echo Most recent subfolder: %b%
cd %b%
echo %%D
find /c "O K" tooling.report
echo %D%
if %errorlevel% equ 1 goto notfound
echo found
goto done
:notfound
echo notfound
goto done
:done
echo %D%
echo now go up
echo !test!
echo %test%
)
pause
I am getting following output:
ECHO is off.
AWC00201
After Nested For
AWC00201
ECHO is off.
Most recent subfolder: 20141103_170658_wro_awc
%D
____________ TOOLING.REPORT: 0
ECHO is off.
notfound
ECHO is off.
now go up
AWC00201
AWC00201
Press any key to continue . . .
Your code has one big problem and one thing to change
The problem is that it is not possible to use goto while inside a for loop and keep the loop iterating. goto cancels the for looping.
The thing to change is your use of variables. You have the information you need inside the for replaceable parameters. Use them. Move the value to a variable when the replaceable parameters does not offer what you need, but this is not the case
#echo off
setlocal enableextensions disabledelayedexpansion
for /F "delims=" %%D in (myfile.txt) do (
cd /d "s:\#vantage\AFG\AWC\AWCU\simulation\WRO_Regression_results\%%D"
for /d %%a in (.) do echo Current folder is "%%~fa"
set "file="
FOR /F "delims=" %%i IN ('dir /b /ad-h /o-d 2 >nul ') DO if not defined file (
set "file=1"
echo subfolder found : %%i
find /c "O K" ".\%%i\tooling.report" >nul 2>nul
if errorlevel 1 (
echo O K found
) else (
echo O K not found or file does not exist
)
)
if not defined file (
echo subfolder not found
)
)
pause

Resources