[input] How to remove trailing and leading whitespace for user-provided input in a batch file?

I know how to do this when the variable is pre-defined. However, when asking for the user to enter in some kind of input, how do I trim leading and trailing whitespace? This is what I have so far:

@echo off

set /p input=:
echo. The input is %input% before

::trim left whitespace
for /f "tokens=* delims= " %%a in ("%input%") do set input=%%a
::trim right whitespace (up to 100 spaces at the end)
for /l %%a in (1,1,100) do if "!input:~-1!"==" " set input=!input:~0,-1! 

echo. The input is %input% after

pause

This question is related to input batch-file whitespace trim

The answer is


for /f "usebackq tokens=*" %%a in (`echo %StringWithLeadingSpaces%`) do set StringWithout=%%a

This is very simple. for without any parameters considers spaces to be delimiters; setting "*" as the tokens parameter causes the program to gather up all the parts of the string that are not spaces and place them into a new string into which it inserts gaps of its own.


You can also strip whitespace by passing in those variables with whitespace as parameters into a sub and then inside your sub simply set them again with the passed in parameters.

@echo off 
set "a=    apple      "
set "b=     banana    "
echo [%a%]
echo [%b%]
call :Strip %a% %b%
pause
goto :EOF

:Strip
set a=%1
set b=%2
echo [%a%]
echo [%b%]

----------------
Results....
[    apple      ]
[     banana    ]
[apple]
[banana]
Press any key to continue . . .

I did it like this (temporarily turning on delayed expansion):

      ...
sqlcmd -b -S %COMPUTERNAME% -E -d %DBNAME% -Q "SELECT label from document WHERE label = '%DOCID%';" -h-1 -o Result.txt
      if errorlevel 1 goto INVALID
    :: Read SQL result and trim trailing whitespace
    SET /P ITEM=<Result.txt
    @echo ITEM is %ITEM%.
    setlocal enabledelayedexpansion
    for /l %%a in (1,1,100) do if "!ITEM:~-1!"==" " set ITEM=!ITEM:~0,-1!
    setlocal disabledelayedexpansion
    @echo Var ITEM=%ITEM% now has trailing spaces trimmed.
....

A very short & easy solution i'm using is this:

@ECHO OFF

SET /p NAME=- NAME ? 
ECHO "%NAME%"
CALL :TRIM %NAME% NAME
ECHO "%NAME%"
PAUSE

:TRIM
SET %2=%1
GOTO :EOF

Results in:

- NAME ?  my_name
" my_name "
"my_name"

The solution below works very well for me.

Only 4 lines and works with most (all?) characters.


Solution:

:Trim
SetLocal EnableDelayedExpansion
set Params=%*
for /f "tokens=1*" %%a in ("!Params!") do EndLocal & set %1=%%b
exit /b

Test:

@echo off

call :Test1 & call :Test2 & call :Test3 & exit /b

:Trim
SetLocal EnableDelayedExpansion
set Params=%*
for /f "tokens=1*" %%a in ("!Params!") do EndLocal & set %1=%%b
exit /b

:Test1
set Value=   a b c   
set Expected=a b c
call :Trim Actual %Value%
if "%Expected%" == "%Actual%" (echo Test1 passed) else (echo Test1 failed)
exit /b

:Test2
SetLocal EnableDelayedExpansion
set Value=   a \ / : * ? " ' < > | ` ~ @ # $ [ ] & ( ) + - _ = z    
set Expected=a \ / : * ? " ' < > | ` ~ @ # $ [ ] & ( ) + - _ = z
call :Trim Actual !Value!
if !Expected! == !Actual! (echo Test2 passed) else (echo Test2 failed)
exit /b

:Test3
set /p Value="Enter string to trim: " %=%
echo Before: [%Value%]
call :Trim Value %Value%
echo After : [%Value%]
exit /b

  @echo off & setlocal enableextensions
  rem enabledelayedexpansion
  set S=  This  is  a  test
  echo %S%.
  for /f "tokens=* delims= " %%a in ('echo %S%') do set S=%%a
  echo %S%.
  endlocal & goto :EOF

from http://www.netikka.net/tsneti/info/tscmd079.htm

for removing leading spaces.


Just came up with this:

set sString=" hello|123(4) "
call :trimMENew %sString%
echo "%sString%"
exit /b 0

:trimMeNew
set "sString=%~1"
if "%sString:~0,1%" == " " set "sString=%sString:~1%"
if "%sString:~-1%" == " " set "sString=%sString:~0,-1%"
exit /b 0

To improve on Forumpie's answer, the trick is using %*(all params) in the sub:

Edit: Added echo of the TRIM subroutines params, to provide more insight

@ECHO OFF

SET /p NAME=- NAME ? 
ECHO "%NAME%"
CALL :TRIM %NAME%
SET NAME=%TRIMRESULT%
ECHO "%NAME%"

GOTO :EOF

:TRIM
  echo "%1"
  echo "%2"
  echo "%3"
  echo "%4"
  SET TRIMRESULT=%*
GOTO :EOF

This strips leading and trailing spaces, but keeps all spaces between.

"  1 2    3 4    "
"1 2    3 4"

Details of %*: Batch Parameters


set newVarNoSpaces=%someVarWithSpaces: =%


@echo off
setlocal EnableDelayedExpansion
set S=  This  is  a  test
echo %S%.
for /f "tokens=* delims= " %%a in ('echo %S%') do (set b=%%a & set b=!b: =! & echo !b!)
endlocal & goto :EOF

or

@echo off
setlocal EnableDelayedExpansion
set S=  This  is  a  test
echo %S%.
for /f "tokens=* delims= " %%a in ('echo %S%') do (set b=%%a & set b=!b: =_! & echo !b!)
endlocal & goto :EOF

Thank you @Bradley Mountford

I'm using the "Trim Right Whitespace" exactly working on my "Show-Grp-of-UID.CMD". :) Other idea for improvement are welcome.. ^_^


I've found that all solution introduced here are not complete enough for me and does not work in one or another case.

CAUTION:

Seems the stackoverflow incorrectly handles tabulation characters (and loses other characters like \x01) in the copy-pasted code, so the below code might not work if you copy it directly by CTRL+C. Use the link at the end to directly download the scripts.

trim_var.bat:

@echo off

rem drop the output variable value
if not "%~2" == "" if not "%~1" == "%~2" set "%~2="

if not defined %~1 exit /b 0

setlocal DISABLEDELAYEDEXPANSION

rem Load and replace a value quote characters by the \x01 character.
call set "RETURN_VALUE=%%%~1:"=%%"

:TRIM_LEFT_LOOP
if not defined RETURN_VALUE exit /b 0
if not ^%RETURN_VALUE:~0,1%/ == ^ / if not ^%RETURN_VALUE:~0,1%/ == ^   / goto TRIM_RIGHT_LOOP
set "RETURN_VALUE=%RETURN_VALUE:~1%"
if not defined RETURN_VALUE exit /b 0
goto TRIM_LEFT_LOOP

:TRIM_RIGHT_LOOP
if not defined RETURN_VALUE exit /b 0
if not ^%RETURN_VALUE:~-1%/ == ^ / if not ^%RETURN_VALUE:~-1%/ == ^ / goto TRIM_RIGHT_LOOP_END
set "RETURN_VALUE=%RETURN_VALUE:~0,-1%"
goto TRIM_RIGHT_LOOP

:TRIM_RIGHT_LOOP_END
rem recode quote and exclamation characters
set "__ESC__=^"
set __QUOT__=^"
set "__EXCL__=!"
set "RETURN_VALUE=%RETURN_VALUE:!=!__EXCL__!%"
set "RETURN_VALUE=%RETURN_VALUE:^=!__ESC__!%"
set "RETURN_VALUE=%RETURN_VALUE:=!__QUOT__!%"

rem safe set
setlocal ENABLEDELAYEDEXPANSION
for /F "tokens=* delims=" %%i in ("!RETURN_VALUE!") do for /F "tokens=* delims=" %%j in ("%%i") do (
  endlocal
  endlocal
  if not "%~2" == "" (
    set "%~2=%%j"
  ) else (
    set "%~1=%%j"
  )
)

exit /b 0

echo_var.bat:

@echo off

if not defined %~1 (
  echo.%~2%~3
  exit /b 0
)

setlocal DISABLEDELAYEDEXPANSION

rem Load and replace a value quote characters by the \x01 character.
call set "RETURN_VALUE=%%%~1:"=%%"

rem recode quote and exclamation characters
set "__ESC__=^"
set __QUOT__=^"
set "__EXCL__=!"
set "RETURN_VALUE=%RETURN_VALUE:!=!__EXCL__!%"
set "RETURN_VALUE=%RETURN_VALUE:^=!__ESC__!%"
set "RETURN_VALUE=%RETURN_VALUE:=!__QUOT__!%"

rem safe echo
setlocal ENABLEDELAYEDEXPANSION
for /F "tokens=* delims=" %%i in ("!RETURN_VALUE!") do for /F "tokens=* delims=" %%j in ("%%i") do (
  endlocal
  endlocal
  echo.%~2%%j%~3
)

exit /b 0

test_trim_var.bat:

@echo off

setlocal DISABLEDELAYEDEXPANSION

set myvar1=              1 ! 2 ^| 3 ^& 4 ^^ 5 = 6 , 7 ; 8 * 9 # 0 %% 1 / 2 \ 3 ? 4 ^> 5 ^< 6 " 7             

call "trim_var.bat" myvar1 myvar2

call "echo_var.bat" myvar1 - -
call "echo_var.bat" myvar2 - -

Output:

-                        1 ! 2 | 3 & 4 ^ 5 = 6 , 7 ; 8 * 9 # 0 % 1 / 2 \ 3 ? 4 > 5 < 6 " 7               -
-1 ! 2 | 3 & 4 ^ 5 = 6 , 7 ; 8 * 9 # 0 % 1 / 2 \ 3 ? 4 > 5 < 6 " 7-

The latest implementation: https://sourceforge.net/p/contools/contools/HEAD/tree/trunk/Scripts/Tools/std/trim_var.bat

Pros:

  • Safely handles almost all specific characters like !, %, ^, ".

Cons:

  • The " character replaces by the \x01 character and might be affected by current code page (not tested).

I had to create a Function.

Use it as:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION


set "TextString=    Purple Cows are flying in the Air Tonight         "
echo REM ^^Notice there is whitespace at the start and end of the TextString
echo "!TextString!"
CALL:trimWhiteSpace "!TextString!" OutPutString
echo Resulting Trimmed Text: "!OutPutString!"
echo REM ^^Now there should be no White space at the start or end.

Exit /B

Add this to the bottom of your batch file:

:FUNCTIONS
@REM FUNCTIONS AREA
GOTO:EOF
EXIT /B


::TRIM FUNCTIONS AREA::
:: USAGE:
:: trimWhiteSpace "!InputText!" OutputText
:: Remember to use the "! on the input text, but NOT on the Output text.
:: The Following is Wrong: trimWhiteSpace "!InputText!" !OutputText!
:: ^^Because it has a ! around the OutPutText
:: Make Sure to add " around the InputText when running the call.
:: If you don't add the " then it will only accept the first word before a space.
::Example:
::  set "TextString=    Purple Cows are flying in the Air Tonight         "
::  echo REM ^^Notice there is whitespace at the start and end of the TextString
::  echo "!TextString!"
::  CALL:trimWhiteSpace "!TextString!" OutPutString
::  echo Resulting Trimmed Text: "!OutPutString!"
::  echo REM ^^Now there should be no White space at the start or end.

:trimWhiteSpace
set textToTrim=%~1
CALL:trimWhiteSpaceOnTheRight "!textToTrim!" OutPutString
SET textToTrim=!OutPutString!
CALL:trimWhiteSpaceOnTheLeft "!textToTrim!" OutPutString
SET %2=!OutPutString!
GOTO:EOF

:trimWhiteSpaceOnTheRight
set str=%~1
for /l %%a in (1,1,31) do if "!str:~-1!"==" " set str=!str:~0,-1!
SET %2=%str%
GOTO:EOF

:trimWhiteSpaceOnTheLeft
set str=%~1
for /f "tokens=* delims= " %%a in ("%str%") do set str=%%a
SET %2=%str%
GOTO:EOF

And remember you MUST add "SETLOCAL ENABLEDELAYEDEXPANSION" to the top of your batch file or else none of this will work properly.

SETLOCAL ENABLEDELAYEDEXPANSION
@REM # Remember to add this to the top of your batch file.

The :trimAll subroutine below:

  • trims leading and trailing tabs and spaces from the string passed to it
  • can be safely CALLed with delayed expansion disabled or enabled
  • handles poison characters (eg, !, %, ^, etc.)
  • CRs and LFs are not supported

Read comments for references and info.

@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=" & if not defined cr for /f "skip=1" %%C in (
    'echo(^|replace ? . /w /u'
) do 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

HTH and HNY! ;)


I'd like to present a compact solution using a call by reference (yes, "batch" has pointers too!) to a function, and a "subfunction":

  @ECHO OFF
  SETLOCAL ENABLEDELAYEDEXPANSION

  SET /p NAME=- NAME ? 
  ECHO "%NAME%"
  CALL :TRIM NAME
  ECHO "%NAME%"
  GOTO :EOF

  :TRIM
  SetLocal EnableDelayedExpansion
  Call :TRIMSUB %%%1%%
  EndLocal & set %1=%tempvar%
  GOTO :EOF

  :TRIMSUB
  set tempvar=%*
  GOTO :EOF

This was my quick-and-dirty solution. Note that it will have unexpected results if the input text has characters that are forbidden in file names.

@echo off
set /p input=Enter some text with spaces before and after^>
echo "%input%"
for /f "tokens=*" %%i in ('echo %input%') do set trimmed=%%~nxi
echo "%trimmed%"

EDIT

To provide a more robust text input character set and still remove the single trailing space that would normally be left by the for in ('echo...') approach, this is an alternative:

set /p input=Enter some text with spaces before and after^>
for /f "tokens=*" %%i in ('echo %input%') do set j=%%i
set trimmed=%j:~0,-1%
echo "%trimmed%"

Examples related to input

Angular 4 - get input value React - clearing an input value after form submit Min and max value of input in angular4 application Disable Button in Angular 2 Angular2 - Input Field To Accept Only Numbers How to validate white spaces/empty spaces? [Angular 2] Can't bind to 'ngModel' since it isn't a known property of 'input' Mask for an Input to allow phone numbers? File upload from <input type="file"> Why does the html input with type "number" allow the letter 'e' to be entered in the field?

Examples related to batch-file

'ls' is not recognized as an internal or external command, operable program or batch file '' is not recognized as an internal or external command, operable program or batch file XCOPY: Overwrite all without prompt in BATCH CanĀ“t run .bat file under windows 10 Execute a batch file on a remote PC using a batch file on local PC Windows batch - concatenate multiple text files into one How do I create a shortcut via command-line in Windows? Getting Error:JRE_HOME variable is not defined correctly when trying to run startup.bat of Apache-Tomcat Curl not recognized as an internal or external command, operable program or batch file Best way to script remote SSH commands in Batch (Windows)

Examples related to whitespace

How to create string with multiple spaces in JavaScript git: fatal: I don't handle protocol '??http' Show whitespace characters in Visual Studio Code What is the symbol for whitespace in C? How to print variables without spaces between values Trim whitespace from a String How do I escape spaces in path for scp copy in Linux? Avoid line break between html elements Remove "whitespace" between div element How to remove all white spaces in java

Examples related to trim

How to remove whitespace from a string in typescript? Strip / trim all strings of a dataframe Best way to verify string is empty or null Does swift have a trim method on String? Trim specific character from a string Trim whitespace from a String Remove last specific character in a string c# How to delete specific characters from a string in Ruby? How to Remove the last char of String in C#? How to use a TRIM function in SQL Server