Home > OS >  Pare down a variable to all after last space
Pare down a variable to all after last space

Time:01-11

I have the following which pares down a folder name (FOLDER) to only all text preceding the first space (tmpFOLDER).

@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0" || exit /B
for %%I in (..) do set "FOLDER=%%~nxI"
for /f "tokens=1 delims= " %%a in ("%FOLDER%") do set tmpFOLDER=%%a

ECHO %FOLDER%
ECHO %tmpFOLDER%

popd
endlocal

PRIMARY REQUEST:

Is there a way to do this in reverse?

Folder name (%FOLDER%): Smith - John

Example current (%tmpFOLDER%): Smith

Example desired (%tmpFOLDER%): John

SECONDARY:

Is there a way to do this with files, as well, disregarding any filetypes (ie. .txt)?

File name (%FILE%): "Smith - John.txt"

Example current (%tmpFILE%): Smith

Example desired (%tmpFILE%): John

CodePudding user response:

The for /F loop cannot extract tokens counted from the end of a string. However, you could use a standard for loop that walks through the words of the file or directory names:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Retrieve base name of grand-parent directory of this script:
for /D %%I in ("%~dp0..") do set "FOLDER=%%~nI"
echo Old name: "%FOLDER%"

set "PREV=" & set "COLL="
rem /* Unnecessary loop iterating once and returning the whole directory name;
rem    it is just here to demonstrate how to handle also more than one names: */
for /F "delims= eol=|" %%L in ("%FOLDER%") do (
    rem // Store current name strng and reset some interim variables:
    set "NAME=%%L" & set "PREV=" & set "COLL= "
    rem // Toggle delayed expansion to avoid issues with `!` and `^`:
    setlocal EnableDelayedExpansion
    rem // Ensure to have each space-separated word quoted, then loop through them:
    for %%K in ("!NAME: =" "!") do (
        rem /* Build new buffer by concatenating word from previous loop iteration,
        rem    then transfer it over `endlocal` barrier (localised environment): */
        for %%J in ("!COLL! !PREV!") do (
            rem // Store current word in an unquoted manner:
            endlocal & set "ITEM=%%~K"
            rem // Store current buffer, store current word for next iteration:
            set "COLL=%%~J" & set "PREV=%%~K"
            setlocal EnableDelayedExpansion
        )
    )
    endlocal
)
rem // Retrieve final result:
set "RESULT=%COLL:~3%"
echo New name: "%RESULT%"
echo Last word: "%PREV%"

endlocal
exit /B

This approach returns the name with the last word removed as well as the last word of the name.


An alternative solution is the sometimes so-called code injection technique, which requires delayed variable expansion and is quite hard to understand:

setlocal EnableDelayedExpansion
echo Old name: "%FOLDER%"
set "RESULT=%FOLDER: =" & set "RESULT=!RESULT!!ITEM!" & set "ITEM= %"
echo New name: "%RESULT%"
echo Last word: "%PREV%"
endlocal

Note, that this will fail when the input string contains !, ^ or " (but the latter cannot occur in file or directory names anyway).

  •  Tags:  
  • Related