Page 1 of 1

A novel method to right trim spaces (and/or periods)

Posted: 14 Jan 2012 10:14
by dbenham
I think aGerman's Macro $RTrim (trim trailing spaces) / also $LTrim and $Trim algorithm for right trimming spaces is the ultimate batch solution.

But I've come up with an interesting alternative: It uses the fact that %~nx1 and %%~nxA trim trailing periods and spaces from file names. This is because Windows does not allow a file name to end with a <space> or a <period>.

Complications for implementing right trim of spaces with this technique are:

1) Trailing periods need to be protected by temporary replacement.

2) The entire string must be interpreted as a file name without any path info by temporary replacement of \ and /.

3) Wildcard characters * and ? will be expanded if the path is valid, and * cannot be easily replaced. The wildcards are protected by temporarily prefixing the string with : which makes it impossible to be a valid filename. This also protects against any drive letter from being removed, and also prevents enclosing quotes from being stripped.

I've implemented RTrimSpaces as a function that cannot be called while delayed expansion is enabled. It can easily be adapted to support delayed expansion calls, and can also be converted into a macro. I did not bother because I still prefer aGerman's algorithm since it can be adapted to trim any character.

Code: Select all

@echo off
cls
setlocal disableDelayedExpansion
set LF=^


set "s1=A Simple test.          "
set "s2=;Another simple test!    "
set "s3=d:\some path with * wildcards ?\some file.some ext         "
set "s4=d:/some path with * wildcards ?/some file.some ext         "
set "s5="nasty quoted chars ^<^&^^^|^>" and unquoted chars <&^|>              "
set "s6="simple quoted text."                           "
set "s7=internal "quoted" text.                   "
set s8="nothing to do                "
set "s9=nothing to do"
set "s10=                           "
set "s11="
set "s12=\/."[ [b[f[d[e             "
for /l %%n in (1 1 12) do call :test s%%n
exit /b

:test
setlocal enableDelayedExpansion
echo(
echo before %~1=[!%~1!]
endlocal
call :RTrimSpaces %1
setlocal enableDelayedExpansion
echo  after %~1=[!%~1!]
exit /b

:RTrimSpaces strVar  --Trims tailing spaces from contents of variable strVar
  if not defined %~1 exit /b
  setlocal enableDelayedExpansion
  set "%~1=!%~1:[=[e!"
  set "%~1=!%~1:\=[b!"
  set "%~1=!%~1:/=[f!"
  set "%~1=!%~1:.=[d!"
  for /f "delims=" %%A in (":!%~1!") do endlocal&set "%~1=%%~nxA"
  setlocal enableDelayedExpansion
  set "%~1=!%~1:~1!"
  if not defined %~1 endlocal&set "%~1="&exit /b
  set "%~1=!%~1:[d=.!"
  set "%~1=!%~1:[f=/!"
  set "%~1=!%~1:[b=\!"
  set "%~1=!%~1:[e=[!"
  for /f eol^=^^^%LF%%LF%^%LF%%LF%^ delims^= %%A in ("!%~1!") do endlocal&set "%~1=%%A"
exit /b


Dave Benham

Re: A novel method to right trim spaces (and/or periods)

Posted: 02 Apr 2012 21:38
by Aacini
Dave: I have simplified your code a little by grouping the several temporary replacements in one FOR command:

Code: Select all

:RTrimSpaces strVar  --Trims tailing spaces from contents of variable strVar
  if not defined %~1 exit /b
  setlocal enableDelayedExpansion
  for %%A in ("[=[e" "\=[b" "/=[f" ".=[d") do set "%~1=!%~1:%%~A!"
  for /f "delims=" %%A in (":!%~1!") do endlocal&set "%~1=%%~nxA"
  setlocal enableDelayedExpansion
  set "%~1=!%~1:~1!"
  if not defined %~1 endlocal&set "%~1="&exit /b
  for %%A in ("[d=." "[f=/" "[b=\" "[e=[") do set "%~1=!%~1:%%~A!"
  for /f eol^=^^^%LF%%LF%^%LF%%LF%^ delims^= %%A in ("!%~1!") do endlocal&set "%~1=%%A"
exit /b

Antonio

Re: A novel method to right trim spaces (and/or periods)

Posted: 03 Apr 2012 05:45
by dbenham
Thanks - I like it :)

Dave Benham