1.

Solve : How to ECHO without a terminating CR/LF?

Answer»

One batch file creates text thus
ECHO "The First chunk of information" > TEXT.TXT

A second batch file subsequently appends with
ECHO "The Second chunk of information" >> TEXT.TXT

TYPE TEXT.TXT shows the two chunks on two separate lines.

Is there any convenient way to avoid the termination so that both chunks appear on a single line.

Regards
Alan
Quote

Is there any convenient way to avoid the termination so that both chunks appear on a single line.

Not really but this solution is specific to your request:

Code: [Select]echo off
ECHO "The First chunk of information" > TEXT.TXT
set /p var=<text.txt
echo %var% "The Second chunk of information"

 
Thank you

Excellent solution that worked until I used it !!!
It has taken me most of today to devise a dirty workaround.
I would appreciate advise for a more elegant solution.

I have used 3 blocks of almost identical code, 5 lines per block.
The only difference are that Block 1 defines X2 and X3, 2 defines X4 and X5, 3 defines X6 and X7
Each block shows the X? defined up to that stage, and concludes with a line beginning "C: ; "

The first block is executed unconditionally - perfect.

The second block fails because it is subject to
IF 1==1 (
  code_block
)

The third block succeeds, and is subject to the "dirty" conditional
IF 1==2 GOTO SKIP
  code_block
:SKIP

After many years of high reliability programming in 'C', where use of GOTO was grounds for a reprimand and possibly the sack, I would much prefer to use the elegant "brackets" solution - even though it is the wrong sort of brackets and I still lapse into 'C' type {} instead of ().

I would also note that although the IF 1==2 GOTO SKIP solution is an grave offence to my sense of decency, it is not inconvenient to use as a single instance, but if I should ever need 100 blocks of conditional code it would be a nightmare having to define and correctly reference and jump to 100 different :SKIP2; :SKIP3; ... ; :SKIP 99; :SKIP100 ETC

I would greatly appreciate advice upon making use of variables within ( ) brackets.

I ran diagnostic code and captured this from the Command window :-

X2=C:
X3=15:52:23.53
DELAY 15:52:23.55 to 15:52:25.10
C: ; 15:52:23.53 ;  ;  ;  ;  ; 15:52:25.10
X2=C:
X3=15:52:23.53
X4=C:
X5=15:52:25.10
DELAY 15:52:25.12 to 15:52:26.62
C: ; 15:52:23.53 ;  ;  ;  ;  ; 15:52:25.10
X2=C:
X3=15:52:23.53
X4=C:
X5=15:52:25.10
X6=C:
X7=15:52:26.64
DELAY 15:52:26.66 to 15:52:28.17
C: ; 15:52:23.53 ; C: ; 15:52:25.10 ; C: ; 15:52:26.64 ; 15:52:28.18
Press any key to continue . . .

In the above, X3 shows Block 1 started at 15:52:23.53
A delay subroutine captured %TIME% before starting a 1.5 second delay and then echoed the captured time value and also the current %TIME% as 15:52:23.55 to 15:52:25.10

After this X5 shows Block 2 started at 15:52:25.10, then the DELAY routine ran from 15:52:25.12 to 15:52:26.62, after which C: ; 15:52:23.53 ;  ;  ;  ;  ; 15:52:25.10
demonstrating that although "SET X" could deliver X4 and X5, ECHO considered them undefined, whilst %TIME% was still stuck at 15:52:25.10, even though DELAY had already seen 15:52:26.62.

In the third block X7 correctly captured 15:52:26.64, 20 mSec after the last DELAY subroutine, the next DELAY ran from 15:52:26.66 to 15:52:28.17,
and the final line was echoed 10 mSec later at 15:52:28.18.  Also, please note that this line now shows the values X4 and X5 which were defined but unusable within block 2, and it also shows the values just defined for X6 and X7.

To summarise, within an IF 1=1 ( code_block ) region,
is it possible to ECHO %VARIABLE% that which has just been defined.

The code I used is shown below

Regards
Alan

ECHO OFF
ECHO %HOMEDRIVE%>K.TXT

SET /P X2=SET X3=%TIME%
SET X
CALL :DELAY
ECHO %X2% ; %X3% ; %X4% ; %X5% ; %X6% ; %X7% ; %TIME%

IF 1==1 (
SET /P X4=SET X5=%TIME%
SET X
CALL :DELAY
ECHO %X2% ; %X3% ; %X4% ; %X5% ; %X6% ; %X7% ; %TIME%
)

IF 1==2 GOTO SKIP
SET /P X6=SET X7=%TIME%
SET X
CALL :DELAY
ECHO %X2% ; %X3% ; %X4% ; %X5% ; %X6% ; %X7% ; %TIME%
:SKIP

PAUSE
GOTO :EOF

:DELAY
SET WAS=%TIME%
ping -w 40 -n 2 127.0.0.1 > nul
ECHO DELAY %WAS% to %TIME%

I'm not entirely sure what you're trying to acheive with the code but i'll give you my view on things...

ECHO OFF
ECHO %HOMEDRIVE%>K.TXT

SET /P X2=SET X3=%TIME%
SET X   --- set X will display all environment variables beginning with X so no need to echo.
CALL :DELAY
ECHO %X2% ; %X3% ; %X4% ; %X5% ; %X6% ; %X7% ; %TIME% -- %3% - %7% aren't defined yet.

IF 1==1 (   ----- why do you need the if 1==1? the code will execute without this... :S
SET /P X4=SET X5=%TIME%
SET X
CALL :DELAY
ECHO %X2% ; %X3% ; %X4% ; %X5% ; %X6% ; %X7% ; %TIME%
)

IF 1==2 GOTO SKIP  --- presumably i'm getting the wrong end of the STICK but if you don't want to run it. Don't write it. also putting this block into () won't run the code without the goto.
SET /P X6=SET X7=%TIME%
SET X
CALL :DELAY
ECHO %X2% ; %X3% ; %X4% ; %X5% ; %X6% ; %X7% ; %TIME%
:SKIP

PAUSE
GOTO :EOF  --- if you religiously don't like goto's then exit would suffice here.

:DELAY
SET WAS=%TIME%
ping -w 40 -n 2 127.0.0.1 > nul
ECHO DELAY %WAS% to %TIME%

FBThe short answer is that I am not having a problem with the comparison test but with the conditional delimiters.

I am not interested in 1==1 nor in 1==2
I am actually testing whether or not the command file was invoked with an argument, so the actual test I perform is    IF %1#==#

I was using code of the form
IF %1#==# (
  SET TIME0=%TIME%
  code_block
  SET T
  ECHO %TIME0% %TIME% >> Sys_Res!.ini
)
The conditional code above is followed by a set of code which extracts information from a start-up file and evaluates against a master copy to decide if I should be alerted to a start-up malfunction.  This extract / evaluate code additionally uses
SET ZZ1=%TIME%, SET ZZ2=%TIME% etc. to obtain time stamps at various stages, and finally
ECHO %ZZ1% %ZZ2% >> Sys_Res!.ini gives me a dump holding diagnostic time stamps.

I really want the conditional code block to also capture and dump diagnostic time stamps.  Unfortunately although SET T is able to find and display TIME0 together with its value, the subsequent ECHO command has nothing at all for %TIMEO%, and what it shows for %TIME% is actually a snapshot of a value FROZEN at the start of this condition code block.

After many hours today exploring how to use the advice by Sidewinder of
set /p var=I now realise that ( ) delimiters seem to be killing me whilst GOTO SKIP seems to do what I need in the "test demonstration" code I previously posted.

I would like to invoke or cancel delayed expansion or whatever it is that causes me problems within ( ) delimiters.   Not only would I consider it more elegant, BUT ALSO I have vague recollections of a similar problem when I wrote code of the form
FOR %%a in (F,G,H,I,J,K) DO (IF EXIST %%a:\ SET R=ON && ECHO At %TIME% Drive %%a:\ %R% >> T.txt )

Now for the long answer ( I am good at these, especially now I am retired.)

Genuine working code is :-

IF %1#==# (
  start "%~N0 %TIME%" /LOW /WAIT %~n0 %TIME%
  if exist H:\ if exist K:\ START C:\PROGRA~1\zabkat\XPLORE~1\XPLORE~1.EXE
  ..\AUTOBACK.EXE C:\Windows\ERDNT\AutoBackup\#Date#_#Time# sysreg curuser otherusers
  EXIT
)
SET ZZ1=%TIME%
ping -w 40 -n 2 127.0.0.1 > nul
SET ZZ2=%TIME%
COPY C:\SYSTEM~1\_RESTO~1\DRIVET~1.TXT /Y
MORE C:\SYSTEM~1\_RESTO~1\DRIVET~1.TXT | FIND /V "C:\" > Sys_Res!.txt
FC Sys_Res!.txt Sys_Res!.cfg && goto HOP0
echo   ERROR   E   E   E   E   E   E   E   ERROR
set /p ANS="*.TXT and *.CFG mismatch. Update CFG ?  Y(es) / N(o) :"
if /I %ANS%#==Y# COPY Sys_Res!.txt Sys_Res!.cfg
:HOP0
DEL Sys_Res!.txt
COPY C:\SYSTEM~1\_RESTO~1\DRIVET~1.TXT *.INI /Y
ECHO %DATE% %1 TO # %ZZ1% # %ZZ2% # %TIME% >> Sys_Res!.ini
EXIT

The above is invoked when I double click on a short cut.  It is also invoked via the
Windows / All Programs / Startup when when I log in to the computer.
Either way, the program starts at NORMAL priority, and because it was launched with no argument %1 is not defined therefore the very first line conditional IF %1#==# is true, so line 2 is executed.

Line 2 runs this same program a second time, with the differences that :-
a) it is started at LOW priority, so that it sits back and waits gazillion seconds for the computer to go through any start-up procedures, and to ensure that System Restore has got around to looking at my external hard drive and has decided whether or not to honour my DEMAND that monitoring be TURNED OFF for all external partitions, or whether it is going ahead regardless of my wishes, and eventually System Restore posts its decision in the file C:\SYSTEM~1\_RESTO~1\DRIVET~1.TXT.
b) it is called with %TIME% as an argument so that for this second time around the first line conditional is no longer true - otherwise it would sit in an endless loop calling itself recursively until a stack overflows or something.

The second time around, at LOW priority, it proceeds from lines 7 through to 20 to create Sys_Res!.txt as a snapshot of what System Restore intends to do to MY external drive.  It then compares this snapshot with my desired configuration held in Sys_Res!.cfg, and if System Restore is disobeying orders it reports an ERROR condition and waits my decision, and this alerts me right at start-up whether I need to reimpose my requirements upon System Restore.  A significant amount of extra code defines variables that are used to append one extra line of diagnostics to the file Sys_Res!.ini.
After this the second time around is complete.

Only after the second time around has completed is the line 2 /WAIT parameter satisfied, then back at NORMAL priority the first time around invocation starts up a couple of programmes which originally were launched via Windows / All Programs / Startup - and then this code completes with a final exit.

The code originally worked perfectly for 100 start-ups WITHOUT the first 7 lines, but then Service Pack 3 struck,  and I was only 80% lucky - once in five start-ups System Restore failed to create C:\SYSTEM~1\_RESTO~1\DRIVET~1.TXT in time for my code to use it.  Lines 1 to 7 cured this perfectly.

I also noticed that the 6 icons in the notification tray (Clock, Volume, Safely Remove Hardware, etc. had a 98% chance of appearing on start-up before SP3, but only a 50% chance with SP3, and sometimes the ONLY icon was the Clock.  For this reason XPLORE~1.EXE and AUTOBACK.EXE have been removed from the frantic muddle at start-up, and deferred until after the system has settled down and established these icons.  This has significantly improved the start-up icon success rate.
I wish to append additional time stamp diagnostics to Sys_Res!.ini as the postponed AUTOBACK.BAT etc are launched, and this is my remaining problem which I now realise is due to the malevolent influence of the conditional delimiters ( ).

Regards
Alan
Yawnnow Merlin that's not very nice... though that is possibly the longest bit of prose i've read since being forced to read Romeo and Juliet at school... Your source code and objectives are far more complex than any i've come across but if it could be summed up in the following sentence: "how do i..." i would feel obliged to try and help.

FBFireballs, I really would appreciate help.

(
SET X2=22
ECHO %X2%
)
It does not work for me if it is within brackets, please tell me how to fix it, and all my problems go away.

I use the ( ) brackets to delimit a block of multiple lines of code.
I may use this block of code for :-
a) Conditional execution subject to IF [NOT] test ( code block );
b) FOR %%a IN (b,c) do (code block).

I find that any variable defined WITHIN that code block is only accessible AFTER that code block.

I have not yet mastered (or needed) "delayed expansion", so I could be wrong, but I suspect I am OBSERVING a "delayed expansion" EFFECT from ( ), and what I need is a way of UN-delayed expansion.

The test code produces this output :-

%a      X1="1111"       X2=""   X3=""   X4=""   X4=""
%a      X1="1111"       X2=""   X3=""   X4=""   X4=""
b       X1="1111"       X2="22" X3=""   X4=""   X4=""
c       X1="1111"       X2="22" X3=""   X4=""   X4=""
%a      X1="1111"       X2="22" X3="yc" X4="z"  X4="5555"
Press any key to continue . . .

What I want to see is :-
%a      X1="1111"       X2=""   X3=""   X4=""   X4=""
%a      X1="1111"       X2="22" X3=""   X4=""   X4=""
b       X1="1111"       X2="22" X3="yb" X4="z"  X4=""
c       X1="1111"       X2="22" X3="yc" X4="zyb" X4=""
%a      X1="1111"       X2="22" X3="yc" X4="zyb" X4="5555"
Press any key to continue . . .


The code which is responsible for the above is :-

ECHO OFF
SET X1=1111
ECHO %%a   X1="%X1%"   X2="%X2%"   X3="%X3%"   X4="%X4%"   X4="%X5%"
(
SET X2=22
ECHO %%a   X1="%X1%"   X2="%X2%"   X3="%X3%"   X4="%X4%"   X4="%X5%"
)
for %%a in (b,c) do (
SET X4=z%X3%
SET X3=y%%a
ECHO %%a   X1="%X1%"   X2="%X2%"   X3="%X3%"   X4="%X4%"   X4="%X5%"
)
SET X5=5555
ECHO %%a   X1="%X1%"   X2="%X2%"   X3="%X3%"   X4="%X4%"   X4="%X5%"
PAUSE


Regards
Alan
Delayed expansion doesn't do what you think. It means it's delayed from expanding when the code is started, instead it expands when the line of code is encountered. From the sounds of it this is what you need.

put this at the top of your code: Code: [Select]set enabledelayedexpansion and then when you use a variable that you want to be evaluated when it's time to execute that line rather than at start use ! instead of % eg.
Code: [Select](
SET X2=22
ECHO !X2!
)

This tells DOS to wait until the line ECHO !X2! is reached before evaluating X2 so the line above has the chance to assign it a value. Hope this helps.

FBThank you - almost a perfect solution.
It pointed me in the right direction and I then found it should not be
set enabledelayedexpansion   but
setlocal enabledelayedexpansion

And that is a perfect cure, thank you so much.

I previously encountered "delayed expansion" as something controlled by /V:ON etc. but was unable to do anything with it !!!

The world is beginning to make sense again

Regards, and many thanks
Alan
sorry i didn't notice that i'd left off the 'local'. The /v:on is an argument when calling cmd.exe

glad everything is making sense again

FB


Discussion

No Comment Found