Pez
Pez

Reputation: 1

Aligning output from batch file For loop

REM ************************ HIGH SCORES TABLE
**********************************************
:highscorestable
set /a count = 0
for /f "tokens=1,2,3 delims=-" %%i in (highscores.txt) do (
set hs=%%i
set hsn=%%j
set hsv=%%k
set hst=%%jscored %%iusing%%k

set hsn1=!hsn!
set hsv1=!hsv!
set hs1=!hs!

set hsn1=               %hsn1%
set hsv1=               %hsv1%
set hs1=               %hs1%
echo %hsn1:~-15%               %hsv1:~-15%               %hs1:~-15%

set /a count+=1
if "!count!"=="5" goto :end
)
:end
echo.
pause

I'm pulling the first 5 lines from a text file using a For loop. My variables populate fine, however I'm struggling with the required alignment.

My ultimate end result should be:

James          Commitment            300
Markos         Excellence            290
Jeremy Si      Party                  50

What obvious thing am I missing here?

Upvotes: 0

Views: 1293

Answers (2)

Compo
Compo

Reputation: 38604

You could try this:

SetLocal EnableDelayedExpansion
REM **************************** HIGH SCORES TABLE ****************************
:highscorestable
Set "count=0"
For /F "UseBackQTokens=1-3Delims=-" %%i In ("highscores.txt") Do (
    Set "hs=%%i"
    Set "hsn=%%j"
    Set "hsv=%%k"
    Set "hst=%%jscored %%iusing%%k"
    Set "hs=   %%i            "
    Set "hsn1=%%j               "
    Set "hsv1=%%k               "
    Echo !hsn1:~,15!!hsv1:~,15!!hs:~-15!
    Set/A count+=1
    If "!count!"=="5" GoTo :end
)
:end
Echo(
Pause

Or without the possibly unnecessary variables:

SetLocal EnableDelayedExpansion
REM **************************** HIGH SCORES TABLE ****************************
:highscorestable
Set "count=0"
For /F "UseBackQTokens=1-3Delims=-" %%i In ("highscores.txt") Do (
    Set "hs=   %%i            "
    Set "hsn=%%j               "
    Set "hsv=%%k               "
    Set "hst=%%jscored %%iusing%%k"
    Echo !hsn:~,15!!hsv:~,15!!hs:~-15!
    Set/A count+=1
    If "!count!"=="5" GoTo :end
)
:end
Echo(
Pause

In both cases, I've added the necessary SetLocal EnableDelayedExpansion line just in case it isn't in your script prior to your provided code.

Edit

You can also alter the code a little forego delayed expansion: (my preferred option)

REM **************************** HIGH SCORES TABLE ****************************
:highscorestable
For /F "Tokens=1-4Delims=:-" %%A In ('FindStr/N $ "highscores.txt"'
) Do If %%A LEq 5 (Set "hst=%%Cscored %%Busing%%D"
    Set "hss=                                 %%B"
    Set "hsn=%%C                                 "
    Set "hsv=%%D                                 "
    Call Echo %%hsn:~,15%%%%hsv:~,15%%%%hss:~-10%%)
Echo(
Pause

Upvotes: 1

Magoo
Magoo

Reputation: 80003

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q46747991.txt"
REM ************************ HIGH SCORES TABLE
REM **********************************************
:highscorestable
set /a count = 0
SET "manyspaces=                                           "
for /f "tokens=1,2,3 delims=-" %%i in (%filename1%) do (
 set hs=%%k&CALL :align hs -8 
 set hsn=%%i&CALL :align hsn 15
 set hsv=%%j&CALL :align hsv 10

 ECHO !hsn!!hsv!!hs!

 set /a count+=1
 if "!count!"=="5" goto end
)
:end
echo.
GOTO :EOF

:align
IF %2 gtr 0 (
 CALL SET "%1=%%%1%%%manyspaces%"
 CALL SET "%1=%%%1:~0,%2%%"
) ELSE (
 CALL SET "%1=%manyspaces%%%%1%%"
 CALL SET "%1=%%%1:~%2%%"
)
GOTO :eof

I edited your results for a source file which I named to suit my system, hence the sequence of coulmns is different from your unpublished source. I changed the metavariable-assignment to suit.

The :align routine peels potatoes by recognising the second argument as the required column-width, positive for left-align and negative for right-align.

The variable manyspaces is set to an obvious value, of sufficient length to cope with the widest column required. Obviously, since it won't change once established, it's best set in the very beginning of the batch.

The routine uses the call set %%var%% method so that it will work regardless of whether delayedexpansion is invoked or not.

The mechanics are, for instance

 CALL SET "%1=%%%1%%%manyspaces%"

with %1=fred

First, parse the command. %1 is replaced by fred and %% by %, yielding

set
"fred=
%fred%[spaces]"

So appends the space-string to the current value of the environment variable specified as %1

The second set - analyse similarly; result is assigned to the environment variable specified as %1

So the routine can be used to generate a fixed-width string, appropriately aligned using any ordinary variable, even if the variable has a value of nothing (ie. is undefined)

Upvotes: 0

Related Questions