1

EDIT: Thank you all, Magoo tips fix it , I using the following code:

echo off
cls
setlocal enabledelayedexpansion

for %%f in (*.mov) do (
    set name=%%~nf
    set new_name=!name:*_= !
    echo File renamed from: !name!.mov to:!new_name!.mov
    rename %%f !new_name!.mov
)

This only works if the file name is something_file_name.mov. If original file is only file_name.mov, I end up it only name.mov So using REGEX is the best option. I'm using a tweaked version of Ben Personick and Squashman suggestions.

@echo off
cls
SET "_Regex=^[0-9]*_"

FOR %%F IN (*.mov) DO (
    ECHO.%%~nF | findstr /R "%_Regex%" >nul && (
        FOR /F "Tokens=1* Delims=_" %%f IN ("%%~nxF") DO (
            MOVE /Y "%%F" "%%g"
        )
    )
)

I have some files named 3424_file_name.mov and need to remove the numbers until the first _ so to get file_name.mov Even better would be to set a range to remove like [0-9] Like to do it in cmd windows 7. This is what i got so far, but not working.

cls
setlocal enabledelayedexpansion

for %%f in (*.mov) do (
 set name=%%~nf
 set new_name=%name%:*_=x
 echo %new_name%)
 rename %%f %new_name%.mov
 )

Thanks Alex

6
  • 3
    Please us e the search facility in the top bar to find out about delayed expansion the #1 FAQ in this tag. Since you've invoked delayed expansion, you need to access the changed value of a variable using !varname! instead of %varname% Commented Apr 23, 2018 at 17:56
  • 2
    Also, your set command is incorrect. You need set var1=!var2:*_=x! (note the position of the !s) Commented Apr 23, 2018 at 17:58
  • 1
    You also have to remove the closing parenthesis in the echo line, that ends the scope of the for loop and the rename has no more a %%f var Commented Apr 23, 2018 at 18:03
  • You do not edit your question title to mark the question solved. You chose one of the answers below by clicking on the check mark next to the answer. Commented Apr 24, 2018 at 14:51
  • I highly recommend starting to learn PowerShell. cmd.exe scripting is riddled with arcane syntax and odd quirks. PowerShell is consistent and more readable (see my answer). Commented Apr 24, 2018 at 15:01

3 Answers 3

2

This would do the needful.

Note how I am using MOVE /Y in case the file is read-only, as Rename cannot handle renaming Read-only files.

SETLOCAL
ECHO OFF

SET "_Regex=^[0-9][0-9]*_.*"
SET "_FileGlob=*_*.Mov"
SET "_FilePath=C:\Path"

FOR %%F IN ("%_FilePath%\%_FileGlob%") DO (
    ECHO.%%~nF | FINDSTR /R "%_Regex%" >NUL && (
        FOR /F "Tokens=1* Delims=_" %%f IN ("%%~nxF") DO (
            MOVE /Y "%%~F" "%%~dpF%%~g"
        )
    )
)
ENDLOCAL
Sign up to request clarification or add additional context in comments.

10 Comments

That regular expression will not work with FINDSTR.
Tweaked the SET "Regex=^^[0-9]+.*" to SET "Regex=^[0-9]" and removed %%dp from MOVE /Y "%%F" "%%dpF%%g".
What is the %%dp on MOVE /Y "%%F" "%%dpF%%g" do ?
@SirAleXbox, they are modifiers for the FOR variable. They are explained at the end of the help file for the FOR command.
the Tildes "~" tell the for loop to expand the variable, stripping any double quotes off the ends, and splitting it into different portions based on which other modifiers you present. n = name, x=extention, d=drive, p=path, and so on and so forth.
|
1

You can use the underscore to your advantage if you use a FOR /F command instead. This will allow you to break up the file name into two variables.

@echo off

for /F "tokens=1* delims=_" %%G in ('dir /a-d /b *.mov ^|findstr /RC:"^[0-9][0-9]*_"') do (
    rename "%%~G_%%~H" "%%~H"
)

6 Comments

That would also remove non numeric prefixes
@LotPings, good point. I will change it to pipe it to findstr.
It may have been bettter to have filtered the *.mov files further, more especially because of the possibility of the renamed files being cycled back into the dir command!
What is the ^ on dir /a-d /b *.mov ^ ? and why double [0-9] ?
The caret or circumflex is needed to escape the PIPE. It is always needed when using a FOR /F command to capture output from another command. The caret or circumflex in the FINDSTR command is used to match at the beginning. That is clearly documented in the help for the FINDSTR command.
|
0

This is a simpler task in PowerShell. Example:

Get-ChildItem *.mov | ForEach-Object {
  $fileName = $_.Name
  if ( $fileName -match '^[0-9]+_' ) {
    $newName = $fileName -replace '^[0-9]+_', ''
    Rename-Item $fileName $newName
  }
}

As other have commented, this can redesigned to be shorter and more efficient. Example:

Get-ChildItem *.mov |
  Where-Object { $_.Name -match '^\d+_' } |
  Rename-Item -NewName ($_.Name -replace '^\d+_','')

The purpose here is to illustrate how PowerShell is far more powerful and flexible than cmd.exe batch scripting.

7 Comments

I would think that $name -match would need to be $_.Name -match. Also, how about Rename-Item $_.FullName $($_.Name -replace '^[0-9]+_', '')
…and why not use \d+?
A where could replace the foreach and the if as rename-item accepts piped input. ls [0-9]*_*.mov|?{$_.name -match '^[0-9]+_'}|ren -newname {$_.Name -replace '^[0-9]+_'}
The original is essentially the same as the cmd method, tasking about the same number of lines and using the loops. The second version you wrote as suggested by @LotPings is a much better leverage of the power of Powershell, where the true benefit often stems from the ability to avoid loops.
@BenPersonick Agreed, in my own answers I usually also present the more verbose version Get-ChildItem *_*.mov|Where-Object Name -match '^\d+_(.*)$'|Rename-Item -NewName {$Matches[1]} -WhatIf
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.