Page 1 of 1
technique: string builder in batch
Posted: 10 Feb 2014 18:38
by carlos
I'm thinking about environment variables.
When you set a environment variable cmd sort all the the environment variable block.
Because this, I think that if need concatenate a string using this:
Code: Select all
set "line="
set "line=%line%string1"
set "line=%line%string2"
set "line=%line%string3"
cmd do 4 enviroment block sort (using all the environment variable names).
I want for avoid this. Then I found a way for save variables without use a file, keeping it in memory, using doskey.
Look this code (I use none set command for the concatenation):
Code: Select all
@echo off
(doskey concat==)
for %%# in (
"this"
"is"
"a"
"string"
) do for /f "tokens=1* delims==" %%a in (
'doskey /macros ^| findstr "^concat="'
) do (doskey concat=%%b%%~#)
rem display result
doskey /macros | findstr "^concat="
pause
Re: technique: string builder in batch
Posted: 10 Feb 2014 23:16
by carlos
After test, I found that set is more speedy because is a internal command, and doskey a external command.
The slow part is access to the content of macro variable, using for /f pipe.
Save is fast, but access to the content is slow.
But, I think, that save variables in the macro section, can be useful for other thing.
Re: technique: string builder in batch
Posted: 10 Feb 2014 23:27
by carlos
I found a way of avoid the findstr part.
The idea is use a id that is unused. In this case: the id is "id". With that way: the id block have only 1 variable.
Code: Select all
@echo off
(doskey /exename=id concat==)
for %%# in (
"this"
"is"
"a"
"string"
) do for /f "tokens=1* delims==" %%a in (
'doskey /m:id'
) do (doskey /exename=id concat=%%b%%~#)
rem display result
doskey /m:id
pause
Edit: replaced /macros by /m
Re: technique: string builder in batch
Posted: 11 Feb 2014 00:12
by carlos
I found a new utility for saving variables with doskey
For example:
if we use disable delayed expansion and call to function that use setlocal enabledelayed expansión, we can save the result like a global variable:
example:
Code: Select all
@echo off
setlocal disabledelayedexpansion
call :clean
for /f "tokens=1* delims==" %%a in (
'doskey /m:clean') do echo(%%b
pause
goto :eof
:clean
setlocal enabledelayedexpansion
doskey /exename=clean result=abc
endlocal
goto :eof
Re: technique: string builder in batch
Posted: 17 Feb 2014 03:13
by Ed Dyreen
carlos wrote:I found a new utility for saving variables with doskey
For example:
if we use disable delayed expansion and call to function that use setlocal enabledelayed expansión, we can save the result like a global variable:
example:
Code: Select all
@echo off
setlocal disabledelayedexpansion
call :clean
for /f "tokens=1* delims==" %%a in (
'doskey /m:clean') do echo(%%b
pause
goto :eof
:clean
setlocal enabledelayedexpansion
doskey /exename=clean result=abc
endlocal
goto :eof
good idea, I created 3 functions, passing variables over endlocal is very easy like this
Code: Select all
setlocal
( %setDosKeyMacro_% testMacro_ ) %= transfer variable to doskey =%
endlocal
( %getDosKeyMacro_% testMacro_ ) %= restore variable from doskey =%
( %runDosKeyMacro_% testMacro_, " this, works, ""Thi^^ s^! work^^ s^!"" " ) %= restore variable from doskey and execute =%
Code: Select all
setDosKeyMacro_(testMacro_)
data: 'for %? in (1,2) do if %?==2 (set ║=!*:º=º0!
set ║=!║:"=""!
set "║=!║:^=^^^^!"&call set "║=%^║:^!=º#^!%"&set "║=!║:º#=^^^!"
set ║=!║:""="!
set ║=!║:*=\*!
set ║=!║:\*=º4!
set ║=!║:?=º6!
set ?=&for %? in (!║!) do set ?=!?!ª%?
if "!?!"=="ª^^^!" set ?=###""
set ?=!?:º6=?!
set ?=!?:º4=*!
set ?=!?:º0=º!)&for /f "tokens=1-26delims=ª" %a in ("!?:~3!") do (echo(&<nul set
/p= a=%~a!_
echo(&<nul set/p= b=%~b!_
echo(&<nul set/p= c=%~c!_
endlocal)else setlocal enableDelayedExpansion&set *=^^^!'
[ok:0]
runDosKeyMacro_(testMacro_: this, works, "Thi^ s! work^ s!" )
call: testMacro_, this, works, "Thi^ s! work^ s!"
[ok:0]
a=this_
b=works_
c=Thi^ s! work^ s!_
endoftest Druk op een toets om door te gaan. . .
But I failed to eleminate the call to a generic function ( command variables need percent expansion )
Re: technique: string builder in batch
Posted: 17 Feb 2014 04:21
by carlos
thanks.
I think that for avoid confussions is better use the same id for id and variable name, like this in this case the id is clean and the variable names is clean:
Code: Select all
@echo off
setlocal disabledelayedexpansion
call :func
for /f "tokens=1* delims==" %%a in (
'doskey /m:clean') do echo(%%b
pause
goto :eof
:func
setlocal enabledelayedexpansion
doskey /exename=clean clean=abc
endlocal
goto :eof
Re: technique: string builder in batch
Posted: 19 Feb 2014 10:38
by Ed Dyreen
I did some timeing on executing a dosKey compressed macro;
Code: Select all
original uncompressed;
len=3840_
time=00:00:00,40_
dosKey compressed;
len=546_
time=00:00:01,44_
restored uncompressed;
len=3840_
time=00:00:00,43_
endoftest Druk op een toets om door te gaan. . .
after the macro has been transferred it gets assigned a generic macro which does a lookup of itself in doskey memory then loads, executes and clears the variable. The stored macro needs one generic function call for for loading ( if return to disabledelayed is enabled ) and one for executing ( percent expansion to run command ).
The macro runs slower after compression but some environmental memory is saved.
There is a coding that needs to be done, doskey does not handle double quotes well, it will replace """" with """ corrupting the value. I have no idea why this happens or if this is by design.
Re: technique: string builder in batch
Posted: 23 Feb 2014 08:03
by Ed Dyreen
Found an additional complication;
Code: Select all
doskey.EXE /exename=m _= leadAndTrailSpace
for /f delims^^=^^ eol^^= %%r in ( 'doskey /m:m' ) do echo. &<nul set /p "=#%%r#"
Similar to the set command on win7, any leading spaces are removed !, trailing spaces are preserved.
Code: Select all
doskey.EXE /exename=m _=_ leadingSpace
doskey /m:m
works as expected