Home > Enterprise >  how do I TOUPPER a string using the string's length in Batch?
how do I TOUPPER a string using the string's length in Batch?

Time:09-27

With some help I created a function to grab a string's length. Now using that length, I want to clean an input I received from a shortcut by capitalizing the contents of the string. However, I can't seem to find a way to specify where in the string I want to capitalize the character. I have the rest of the code figured out I think, I just can't find a way to tell where in the string I want to make the changes. This is what I have so far:

@ECHO on
TITLE Navigator
SETLOCAL enabledelayedexpansion

REM | ...file comments...

REM | variable setting, grabbing & cleaning
SET _box=%1
SET _system=%_box:~1,-1%
CALL :STRLEN _system _len
CALL :CLEANER _system _len _cSystem

REM | Results
ECHO Cleaned output: %_cSystem%

PAUSE
ENDLOCAL
EXIT /B %ERRORLEVEL%

REM | ***** Functions *****
REM | String length function (last working @ 09/26/22 TIME)
:STRLEN
  SET $str=!%1!
  SET $len=0
:_STRLEN
  IF NOT DEFINED $str ( goto :END_STRLEN )
  IF NOT "!$str:~%$len%!"=="" (
    SET /A $len =1
    goto :_STRLEN
  )
:END_STRLEN
  SET "%2=!$len!"
  SET $str=
  SET $len=
  EXIT /B 0

REM | String cleaner (currently in progress)
:CLEANER
  SET $str=!%1!
  SET $len=!%2!
:_CLEANER
  IF NOT DEFINED $str ( goto :END_CLEANER )
  IF "$len">=0 (
    SET $str:[POSITION @ $len]=$str:[POSITION @ $len]
    SET /A %$len%-=1
    GOTO :_CLEANER
  )
:END_CLEANER
  SET "%3=!$str!"
  SET $str=
  SET $len=
  EXIT /B 0

The problem is near the bottom at :_CLEANER in the second IF statement where it tries to set a character within the $str string to itself so batch does the uppercasing on its own. Any help on this would be greatly appreciated.

CodePudding user response:

@ECHO OFF
SETLOCAL
set "ucalphas=A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
set "lcalphas=a b c d e f g h i j k l m n o p q r s t u v w x y z"
set "mystring=abcddcbajqz123HELLO teSt"
echo start         %mystring%
call :toupper mystring
echo after toupper %mystring%
call :tolower mystring
echo after tolower %mystring%

GOTO :EOF

:toupper
setlocal enabledelayedexpansion
set "result=!%1!"
for %%s in (%ucalphas%) do set "result=!result:%%s=%%s!"
endlocal&set "%1=%result%"
goto :eof

:tolower
setlocal enabledelayedexpansion
set "result=!%1!"
for %%s in (%lcalphas%) do set "result=!result:%%s=%%s!"
endlocal&set "%1=%result%"
goto :eof

Here's a starter, using string-substitution which replaces the first "string" (ok, it's a character) case-insensitive with the same character (literally).

IF "$len">=0 (

will not work. The comparison is character-for-character. One side is quoted, the other is not. You want the contents of $len, not the literal $len, so %$len% and the comparison operators are ==, equ neq, gtr, geq, lss, leq. All except == must be surrounded by spaces. > is a redirector.

Note the use of set "var=value". This syntax ensures trailing spaces on lines are not included in the value set.

CodePudding user response:

Though you're question is specifically aimed at pure batch-file I am just putting this out there for informational purposes.

For these types of tasks, I would much rather go with Powershell

For instance, we can capitalize the first letter of each word in a string:

$str = 'john m smith'
$result = (Get-Culture).TextInfo
$result.ToTitleCase($str)

Which will result in John M Smith

Evidently, this can be called from a batch-file as:

@echo off
for /f "delims=" %%i in ('powershell "$str = 'john m smith';$result = (Get-Culture).TextInfo;$result.ToTitleCase($str)"') do echo %%i

To push an entire line to lower or upper, we simply use string.toUpper() or `"string".toLower(). So in batch file we could run:

Upper:

for /f "delims=" %%i in ('powershell "$str = 'john m smith';"$str".ToUpper()"') do echo %%i

Lower:

for /f "delims=" %%i in ('powershell "$str = 'john m smith';"$str".ToLower()"') do echo %%i

Then, as a side note, string length can easily be retrieved with "sting".length, again usable as a function in batch-file

for /f "delims=" %%i in ('powershell "$str = 'john m smith';$str.length"') do echo %%i

PS!! These should preferbly be used as standalone ps1 scripts, but I have included the batch-file stings, should you need to incorporate it into an existing large batch-file

  • Related