windowsbatch-filecmdsubstringfilenames

CMD/Batch - Remove substring from filenames


This seems very simple and I've been looking around the net for hours and have found many examples but none of them seem to do "anything" at all for me. Could be they're not batch scripts and are meant for powershell but... I'm trying to create a batch file that will remove specific substring from a filename.

I want to remove the .ru from the following names:

I'm using Windows 11


Solution

  • SOLUTION 1:

    To complement what @magoo said and give an answer a bit more general, you can use a for loop to remove the middle part of the string of the file name to finally use RENAME to rename your files on your file system.

    Here is a working example:

    @echo off
    
    FOR %%e IN (*.ru.txt) DO (
        SET "filename=%%e"
        CALL SET "filename=%%filename:.ru=%%"
        CALL ECHO %%filename%%
        CALL RENAME %%e %%filename%%
    )
    

    Note
    This solution will search across all your directories available to cmd, it includes the current directory and the directories available in your PATH environment variable.

    In case you encounter a The syntax of the command is incorrect. error, you can try to put both %%e and %%filename%% inside double quotes (") which will make your last line like this:

    CALL RENAME "%%e" "%%filename%%"
    

    SOLUTION 2:

    The solution provided by @Compo which will work only on the given file names but is simpler and has less performance concerns is:

    @For %%G In (test.ru.tx, thisone.ru.txt, anotherone.ru.txt, "one with spaces.ru.ext") Do @For %%H In ("%%~nG") Do @Ren "%%~G" "%%~nH%%~xG"
    

    SOLUTION 3:

    @Mofi raised the subject of performance issues with the first solution, firstly about the use of call.

    He knows how to explain a lot better than me so here are his comments:

    I suggest reading this answer where I have explained in detail what is the problem with call used in a for loop for an additional parsing of the command line before execution.

    The for loop in your answer uses CALL SET, CALL ECHO and CALL RENAME resulting in searching on each file to rename in the current directory and next in all directories of PATH for SET.*, ECHO.* and RENAME.* which makes file rename operation on hundreds or thousands of files to rename quite slow due the thousands of file system accesses.

    and

    I suggest further in reading the issue chapters in this answer and "At which point does for or for /R enumerate the directory (tree)?" on being interested in even more deep facts about for loop processing.

    The solution proved by Mofi:

    @for /F "eol=| delims=" %%G in ('dir *.ru.tx /A-D /B 2^>nul') do @for %%H in ("%%~nG") do @ren "%%G" "%%~nH%%~xG"
    

    For more information on how does RENAME work and its behavior with wildcards, this Super User post might be useful: How does the Windows RENAME command interpret wildcards?