-2

I have some problem writing a code for a batchfile that will replace the first part of a file name.

let say we have the files:

abcd123.txt
abcd345.txt

the numeric part(and the extensions) is the part I want to keep and change it to blabla123.txt and blabla345.txt
the numeric part is not always the same.

I tried to write:

set FILE =%1
set LastPart =  %FILE:~-7%
set NewName =   c:\MyFolder\blabla%LastPart%
ren %FILE% %NewName%

but it didn't worked because there's space between c:\MyFolder\blabla to 123.txt

Pang
  • 9,564
  • 146
  • 81
  • 122
MSm
  • 125
  • 4
  • If a filename contains spaces, enclose it in double quotes ("). Also, don't put spaces around the = in the set command, otherwise the space becomes part of the value. – Klitos Kyriacou Sep 20 '16 at 23:06
  • 1. Your code does not fit the description! 2. Are the lengths of both string and number parts always the same? what to do if there is something like `abc123def456.txt`? what to keep and what to remove then? – aschipfl Sep 21 '16 at 08:56

3 Answers3

0

Please see if below script helps you. It iterates through all files in a given directory and renames them according to your requirement.

@echo OFF
setlocal ENABLEDELAYEDEXPANSION
REM Get input directory from user
set /p INPUT_DIR=Please enter full path to directory with files, use double quotes if any space:
cd /d %INPUT_DIR%
for /f %%f in ('dir /b %INPUT_DIR%') do (
    set newname=hello!fullname:~-7!
    ren %%f !newname!
)

Output

E:>dir /b "E:\Temporary\SO\batch\Input - Space"

adadadadad123.txt

E:>Temporary\SO\batch\test_ren.bat

Please enter full path to directory with files, use double quotes if any space:"E:\Temporary\SO\batch\Input - Space"

E:>dir /b "E:\Temporary\SO\batch\Input - Space"

hello123.txt

  • what the ! symbol do? I tried to use it but it did nothing – MSm Sep 20 '16 at 23:11
  • Please read about delayed expansion here http://ss64.com/nt/delayedexpansion.html –  Sep 20 '16 at 23:15
  • Did nothing? Do you mean it didn't rename the files as expected? –  Sep 20 '16 at 23:17
  • Try the solution I provided below. It was deliberately structured to match your question such that it would be read with the same level of understanding. – Compo Sep 21 '16 at 10:40
0

Perhaps:

SET "OldName=%~n1"
SET "Ext=%~x1"
SET "LastPart=%OldName:~-3%"
SET "FirstPart=blabla
SET "NewFold=C:\MyFolder"
REN "%~1" "%NewFold%\%FirstPart%%LastPart%%Ext%"
Compo
  • 36,585
  • 5
  • 27
  • 39
0

Although the question is not quite clear to me, I decided to provide an answer, because the task of extracting a numeric part from the end of a string appears not to be that trivial, particularly in case both the preceding string and the numeric portions may have different lengths.

So here is a script that accepts file paths/names/patterns provided as command line arguments, splits off ther numeric part, prepends an optional prefix to it and renames the file accordingly (actually it just echoes the ren command line for testing; remove the upper-case ECHO to actually rename):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "PREFIX="

for %%F in (%*) do (
    for /F "tokens=1-2 delims=0123456789 eol=0" %%K in ("_%%~nF") do (
        if "%%L"=="" (
            set "FLOC=%%~F"
            set "FILE=%%~nF"
            set "FEXT=%%~xF"
            set "FNEW="
            setlocal EnableDelayedExpansion
            set "FILE=_!FILE!"
            for /L %%E in (0,1,9) do (
                set "NAME=!FILE:*%%E=%%E!"
                if not "!NAME!"=="!FILE!" (
                    if 1!NAME! GTR 1!FNEW! (
                        set "FNEW=!NAME!"
                    )
                )
            )
            ECHO ren "!FLOC!" "!PREFIX!!FNEW!!FEXT!"
            endlocal
        )
    )
)

endlocal
exit /B

The script skips all files that have less or more than exactly one numeric part in their names, and also those where the numeric part is followed by something other than the file name extension. For example, abcd1234.txt is processed, whereas abcd.txt, 1234.txt, ab1234cd.txt, 1234abcd.txt and ab12cd34.txt are skipped. Note that the numeric part is limited to nine decimal figures.


If the limit of nine digits is disturbing, the following script can be used. It is very similar to the aforementioned one, but a numeric comparison has been replaced by a string comparison with the numbers padded by leading zeroes to have equal lengths. Therefore the string comparison provides the same result as a pure numeric comparison:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "PREFIX="

set /A "DIGS=256"
setlocal EnableDelayedExpansion
for /L %%E in (1,1,%DIGS%) do set "PADZ=!PADZ!0"
endlocal & set "PADZ=%PADZ%"
for %%F in (%*) do (
    for /F "tokens=1-2 delims=0123456789 eol=0" %%K in ("_%%~nF") do (
        if "%%L"=="" (
            set "FLOC=%%~F"
            set "FILE=%%~nF"
            set "FEXT=%%~xF"
            set "FNEW="
            setlocal EnableDelayedExpansion
            set "FILE=_!FILE!"
            for /L %%E in (0,1,9) do (
                set "NAME=!FILE:*%%E=%%E!"
                if not "!NAME!"=="!FILE!" (
                    set "CMPN=%PADZ%!NAME!"
                    set "CMPF=%PADZ%!FNEW!"
                    if "!CMPN:~-%DIGS%!" GTR "!CMPF:~-%DIGS%!" (
                        set "FNEW=!NAME!"
                    )
                )
            )
            ECHO ren "!FLOC!" "!PREFIX!!FNEW!!FEXT!"
            endlocal
        )
    )
)

endlocal
exit /B

This is a robust and more flexible approach, which allows to specify what numeric part to extract by its (zero-based) index, in the variable INDEX (a negative value counts from the back, so -1 points to the last one, if you prefer that):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "PREFIX=blah" & rem // (optional prefix to be used for the new file names)
set /A "INDEX=0"  & rem // (`0` means first numeric part, `-1` means last one)

rem // Loop through command line arguments:
for %%F in (%*) do (
    set /A "CNT=-1" & set "KIND="
    for /F "delims== eol=" %%E in ('2^> nul set "$PART["') do set "%%E="
    rem // Store information about currently iterated file:
    set "FLOC=%%~F"
    set "FILE=%%~nF"
    set "FEXT=%%~xF"
    rem // Toggle delayed expansion to avoid troubles with `!`:
    setlocal EnableDelayedExpansion
    rem // Assemble a list of file name portions of numeric and non-numeric parts:
    set "LIST= "!FILE!" "
    for /L %%J in (0,1,9) do set "LIST=!LIST:%%J=" %%J "!"
    set "LIST=!LIST: "" =!"
    rem // Determine file name portions, together with their count and kinds:
    for %%I in (!LIST!) do (
        endlocal & set /A "CNT+=1"
        set "ITEM=%%~I" & set "TEST=%%I"
        setlocal EnableDelayedExpansion
        if "!TEST!"=="!ITEM!" (set "KND=0") else (set "KND=-")
        for /F %%K in ("KIND=!KIND!!KND!") do (
            for /F "delims=" %%E in ("$PART[!CNT!]=!ITEM!") do (
                endlocal & set "%%K" & set "%%E"
            )
        )
        setlocal EnableDelayedExpansion
    )
    rem // Retrieve the desired numeric file name portion:
    if %INDEX% lss 0 (set /A "INDEX=-(1+INDEX)")
    if %INDEX% lss 0 (set "RANGE=!CNT!,-1,0") else (set "RANGE=0,1,!CNT!")
    set /A "IDX=-1" & set "FNEW=" & for /L %%J in (!RANGE!) do (
        if "!KIND:~%%J,1!"=="0" set /A "IDX+=1" & (
            if !IDX! equ !INDEX! for %%I in (!IDX!) do set "FNEW=!$PART[%%J]!"
        )
    )
    rem // Actually rename file:
    if defined FNEW (
        ECHO ren "!FLOC!" "!PREFIX!!FNEW!!FEXT!"
    )
    endlocal
)

endlocal
exit /B
aschipfl
  • 33,626
  • 12
  • 54
  • 99