Page 1 of 1
String manipulation - remove leading and trailing spaces
Posted: 05 Aug 2019 13:51
by Eureka!
Just reading the
String Manipulation page.
There is another way - beside the ones mentioned on that page - to remove leading and trailing spaces:
Code: Select all
set str= 15 Leading and Trailing Spaces to truncate &rem
echo."%str%"
for /f "tokens=*" %%A in ("%str%") do set str=%%~pnxA
set str=%str:~1%
echo."%str%"
OUTPUT:
Code: Select all
" 15 Leading and Trailing Spaces to truncate "
"15 Leading and Trailing Spaces to truncate"
The %~pnxA will cause the string to be seen as a filename, without checking if it is an existing one.
Reporting path filename and extension will cause a leading "\" (from the path) that has to be stripped before getting the "unspaced" string.
HTH.
(obviously you should't use this method when the string contains a filename ..)
Re: String manipulation - remove leading and trailing spaces
Posted: 07 Aug 2019 15:27
by Sponge Belly
Hi Eureka!
Welcome to the forum!
Dave Benham explored this approach in the
novel method to right-trim spaces topic back in January, 2012.
As pointed out at the time, the method had too many shortcomings to ever be a general-purpose solution, and development ceased.
But trimming leading and trailing whitespace from a string was an obsession of mine. After many failed attempts, I eventually came up with the following code (see comments for credits):
Code: Select all
@echo off & setLocal enableExtensions disableDelayedExpansion
:: https://www.dostips.com/forum/viewtopic.php?t=4308
(call;) %= sets errorLevel to 0 =%
(set lf=^
%= BLANK LINE REQUIRED =%
)
:: kudos to carlos for superior method of capturing CR
:: https://www.dostips.com/forum/viewtopic.php?p=40757#p40757
set "cr=" & for /f "skip=1" %%C in (
'echo(^|replace ? . /w /u'
) do if not defined cr set "cr=%%C"
set ^"orig= !random! ! ^^! ^^^^! ^"^^ ^&^"^& ^^^" %%os%% ^"
call :trimAll res1 orig
setLocal enableDelayedExpansion
call :trimAll res2 orig
echo(orig: [!orig!]
echo(res1: [!res1!]
echo(res2: [!res2!]
endLocal
endLocal & goto :EOF
:trimAll result= original=
:: trims leading and trailing whitespace from a string
:: special thanks to jeb for
:: https://stackoverflow.com/a/8257951
setLocal
set "ddx=!" %= is delayed expansion enabled or disabled? =%
setLocal enableDelayedExpansion
set "die=" & if not defined %2 (
>&2 echo( ERROR: var "%2" not defined & set "die=1"
) else set "str=!%2!" %= if =%
if not defined die for %%L in ("!lf!") ^
do if "!str!" neq "!str:%%~L=!" (
>&2 echo( ERROR: var "%2" contains linefeeds & set "die=1"
) %= if =%
if not defined die for %%C in ("!cr!") ^
do if "!str!" neq "!str:%%~C=!" (
>&2 echo( ERROR: var "%2" contains carriage returns
set "die=1"
) %= if =%
if defined die goto die
(for /f eol^= %%A in ("!str!") do rem nop
) || (
>&2 echo(WARNING: var "%2" consists entirely of whitespace
endLocal & endLocal & set "%1=" & exit /b 0
) %= cond exec =%
:: prepare string for trimming...
:: double carets
set "str=!str:^=^^^^!"
:: double quotes
set "str=!str:"=""!"
:: escape exclaims
set "str=%str:!=^^^!%" !
:: act of CALLing subfunction with
:: expanded string trims trailing whitespace
call :_trimAll "%%str%%
:: prepare string to be passed over endLocal boundary...
:: double carets again if delayed expansion enabled
if not defined ddx set "str=!str:^=^^^^!"
:: escape exclaims again if delayed expansion enabled
if not defined ddx set "str=%str:!=^^^!%" !
:: restore quotes
set "str=!str:""="!"
:: pass string over endLocal boundary and trim leading whitespace
for /f tokens^=*^ eol^= %%a in ("!str!") do (
endLocal & endLocal & set "%1=%%a" !
) %= for /f =%
exit /b 0
:die
endLocal & endLocal & set "%1=" & exit /b 1
:_trimAll
:: subfunction
:: trailing exclaim is required as explained by jeb at
:: https://www.dostips.com/forum/viewtopic.php?p=6933#p6933
set "str=%~1" !
exit /b 0
Impenetrable spaghetti even Ed Dyreen would disown! Yes, it works. But look at the hoops you have to jump through first. Completely impractical. I’ve come to realise that just because something can be done in Batch, it doesn’t necessarily mean it should be.
Laters!
- SB
Re: String manipulation - remove leading and trailing spaces
Posted: 11 Aug 2019 08:24
by Eureka!
Thanks!
... a general-purpose solution ...
I never had the illusion that this was a universal solution. Most times you know what format/layout the output will be. And if suitable, this is a short, straightforward fix.
(But hadn't thought about %'s and /'s)
Sponge Belly wrote: ↑07 Aug 2019 15:27
Impenetrable spaghetti even Ed Dyreen would disown!
Well, I could follow the flow. (not that I think that I'm able to reproduce it ...)
A lot of 'protection layers' to send strings through secondary shells (for command; pipes)
Not that I would encourage you to extend this even further, but it looks like it doesn't handle strings with % in them (not tested, though)
Thanks for your feedback. Appreciated!
BTW: I really liked your %= ... =% approach. I think I am going to use that too.