Как удалить конечные и начальные пробелы для пользовательского ввода в командном файле? - PullRequest
30 голосов
/ 09 июня 2010

Я знаю, как это сделать, когда переменная предопределена. Тем не менее, при запросе ввода пользователем какого-либо ввода, как мне обрезать начальные и конечные пробелы? Это то, что я до сих пор:

@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

Ответы [ 13 ]

25 голосов
/ 09 июня 2010

Вам необходимо включить отложенное расширение.Попробуйте это:

@echo off
setlocal enabledelayedexpansion
:blah
set /p input=:
echo."%input%"
for /f "tokens=* delims= " %%a in ("%input%") do set input=%%a
for /l %%a in (1,1,100) do if "!input:~-1!"==" " set input=!input:~0,-1!
echo."%input%"
pause
goto blah
21 голосов
/ 28 сентября 2014

Решение, приведенное ниже, работает очень хорошо для меня.

Только 4 строки и работает с большинством (всех?) Символов .


Решение:

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

Тест:

@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%]
13 голосов
/ 23 августа 2012

Очень короткое и простое решение, которое я использую, таково:

@ECHO OFF

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

:TRIM
SET %2=%1
GOTO :EOF

Результат:

- NAME ?  my_name
" my_name "
"my_name"
5 голосов
/ 30 октября 2013

Я хотел бы представить компактное решение, использующее вызов по ссылке (да, «пакет» также имеет указатели!) На функцию и «подфункцию»:

  @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
2 голосов
/ 19 августа 2015

Чтобы улучшить ответ Forumpie, трюк использует %* (все параметры) в подпункте:

Редактировать: Добавлен эхо параметров Params подпрограмм TRIM, чтобы обеспечить больше понимания

@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

Удаляет начальные и конечные пробелы, но сохраняет все пробелы между.

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

Сведения о% *: Параметры партии

0 голосов
/ 04 января 2019
for /f "usebackq tokens=*" %%a in (`echo %StringWithLeadingSpaces%`) do set StringWithout=%%a

Это очень просто. for без каких-либо параметров считает пробелы разделителями; установка «*» в качестве параметра tokens приводит к тому, что программа собирает все части строки, которые не являются пробелами, и помещает их в новую строку, в которую она вставляет свои собственные пробелы.

0 голосов
/ 01 января 2018

Подпрограмма :trimAll ниже:

  • обрезает начальные и конечные табуляции и пробелы из строки, переданной ей
  • можно безопасно вызывать с отключенным или включенным отложенным расширением
  • обрабатывает отравленные символы (например, !, %, ^ и т. Д.)
  • CR и LF не поддерживаются

Читайте комментарии для справок и информации.

@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 и HNY! ;)

0 голосов
/ 02 сентября 2017

set newVarNoSpaces =% someVarWithSpaces: =%

0 голосов
/ 03 июля 2014

Вы также можете удалить пробелы, передав эти переменные с пробелами в качестве параметров в подпрограмму, а затем внутри своей подпрограммы просто установите их снова с переданными параметрами.

@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 . . .
0 голосов
/ 10 сентября 2013

Thank you @Bradley Mountford

Я использую «Trim Right Whitespace», точно работая над моим «Show-Grp-of-UID.CMD».:) Другие идеи для улучшения приветствуются .. ^ _ ^

...