Rename files by removing part of their existing basename - windows

I have a folder where all my multipass 3d renders are going. I had to start and stop the renders several times which lead to name changes.
names:
Mask_Opening_Scene_Multipass_i1_0230.exr
Mask_Opening_Scene_Multipass_i1_0231.exr
Mask_Opening_Scene_Multipass_i1_0232.exr
The bulk of the files are named:
Mask_Opening_Scene_Multipass0230.exr
So what I need, is to remove the, _i1_
Here is what I have:
#echo off
set list="*_il_*"
echo List of files
echo.
echo.
for /r %%a in (%list%) do (
set file=%%a
echo "!file!" "!File:_i1_=!")
)
pause
Can anyone help me out?

#echo off
setlocal enabledelayedexpansion
set "list=*_il_*"
echo List of files
echo.
echo.
for /f %%a in (%list%) do (
set file=%%a
echo "!file!" "%File:_i1_=%")
pause
or
#echo off
setlocal enabledelayedexpansion
set "list=*_il_*"
echo List of files
echo.
echo.
for /f %%a in (%list%) do (
set file=%%a
echo "!file!" "!File:_i1_=!")
pause
First, you don't have the delayed expansion enabled, so you cant use the variables with "!".
Then, you use /r instead of /f, /r is for paths, /f is for files, so probably is catch a error using /r.
You don't have to especify whats the _i1_ gonna be, you can only put %file:_i1_=%, will make the name disapear, and i think that the delayed var (!) is not necessary for the variables...
I hope i helped you.

Related

How to remove errors and commands displaying in command line window?

Based on several articles on the internet I have written a batch script that:
scans defined location looking for .png files,
creates path to the new location for each file (..\first 4 characters of filename\first 9 characters of filename)
moves files to the new location
The script works fine, however I would like it to stop displaying errors and commands in command line window and display "PROCESSING..." instead? I have tried echo off, >nul and 2>nul with no success.
Here's the script:
#echo off
setlocal enabledelayedexpansion
cls
pushd E:\Archiwum\
for /f "tokens=*" %%1 in ('dir /a-d /b E:\Archiwum\*.png') do (
set filename=%%1&set dirname=!filename:~0,4!\!filename:~0,9!
if not exist E:\Archiwum\!dirname! (md E:\Archiwum\!dirname!)
move %%1 E:\Archiwum\!dirname!\
)
Here's a quick rewrite of your script
#Echo Off
If Exist "E:\Archiwum\*.png" (CD /D "E:\Archiwum") Else Exit /B
SetLocal EnableDelayedExpansion
ClS
For %%A In (*.png) Do (Echo Processing %%A
Set "filename=%%~nA"
Set "dirname=!filename:~,4!\!filename:~,9!"
If Not Exist "!dirname!\" MD "!dirname!"
If Exist "!dirname!\%%A" (Echo Name conflict %%A already exists.
) Else Move "%%A" "!dirname!" > Nul)
You need to be careful of spaces in your file names in order to prevent having directory names with trailing spaces as well as the other things I mentioned in my comments.
Thanks for your feedback. I made two modifications to your solution and now it works just fine.
#Echo Off
If Exist "C:\Archiwum\*.png" (CD /D "C:\Archiwum") Else Exit /B
SetLocal EnableDelayedExpansion
ClS
#Echo Processing...
#Echo Off
For %%A In (*.png) Do (
Set "filename=%%~nA"
Set "dirname=!filename:~,4!\!filename:~,9!"
If Not Exist "!dirname!\" MD "!dirname!"
If Exist "!dirname!\%%A" (Echo Name conflict %%A already exists.
) Else Move "%%A" "!dirname!" > Nul)
I added second #Echo Off - without it commands from for loop where still shown in command window.
I moved #Echo Processing as I wanted it to be shown only once with all of the operations done in the background.
Thank you a lot for your help.

How to generate automatic numbering of output files in a batch file?

I have a bunch of files say,
xxx111.txt
xxx112.txt
xxx113.txt
I want to remove the last 3 characters of all the file names and I'm using this script
#echo off
setlocal enabledelayedexpansion
set X=3
for %%f in (*) do if %%f neq %~nx0 (
set "filename=%%~nf"
set "filename=!filename:~,-%X%!"
ren "%%f" "!filename!%%~xf"
)
popd
pause
This runs perfectly when the output filenames are different. However, in the above case all file will be output as xxx.txt and the script throws me the error
"A duplicate file name exists, or the file cannot be found".
Is there any way to tweak this so that duplicate files will be renamed and maybe numbered 1,2,3...?
Unfortunately I cannot install any other software.
#echo off
setlocal EnableDelayedExpansion
set X=3
for /F "delims=" %%f in ('dir /A:-D /B') do if "%%f" neq "%~NX0" (
set "filename=%%~Nf"
set "filename=!filename:~,-%X%!"
if exist "!filename!%%~Xf" call :getNewName "%%~Xf"
ren "%%f" "!filename!%%~Xf"
)
popd
pause
goto :EOF
:getNewName ext
set i=0
:nextNum
set /A i+=1
if exist "%filename%%i%%~1" goto nextNum
set "filename=%filename%%i%"
exit /B
You should not use plain for %%f command when renaming files. Depending on where the new names are placed in the list of original names, they may be processed a second time by the for %%f. Always use for /F for renaming.

Batch script: The syntax of the command is incorrect - when script is going trough subdirectories?

Hello folks,
my problem is probably very simple.
When I`m trying to use /r as a reference for batch script to go trough all the folders and subs in order to execute this small script I get the "The syntax of the command is incorrect" error.
#echo off
setlocal enabledelayedexpansion enableextensions
for /r %%f in ("*[]*.*") do (
set oldname=%%f
set newname=!oldname:[]=!
echo !oldname!
echo !newname!
pause
ren !oldname! !newname!
)
However, when I remove /r this actually works, without any problem:
#echo off
setlocal enabledelayedexpansion enableextensions
for %%f in ("*[]*.*") do (
set oldname=%%f
set newname=!oldname:[]=!
echo !oldname!
echo !newname!
pause
ren !oldname! !newname!
)
So, how I can make the this script go trough all of the folders and subs, without problems as well?
Thanks
You cannot include path information in the new file name when using REN. You can only include path information when specifying the original file name (and location). Any attempt to use REN with path info in 2nd argument gives the syntax error.
You can use %%~nxf to get just the name and extension of the file. Then do search and replace on that value to come up with the new name.
#echo off
setlocal enabledelayedexpansion
for /r %%F in ("*[]*.*") do (
set "newname=%%~nxF"
set "newname=!newname:[]=!"
echo %%F
echo !newname!
pause
ren "%%F" "!newname!"
)
The above will fail if you ever run into a ! in your original file name (or path). That can be fixed by toggling delayed expansion on and off within the loop.
#echo off
setlocal disableDelayedExpansion
for /r %%F in ("*[]*.*") do (
set "oldname=%%F"
set "newname=%%~nxF"
setlocal enableDelayedExpansion
set "newname=!newname:[]=!"
echo !oldname!
echo !newname!
pause
ren "!oldname!" "!newname!"
endlocal
)
Your problem stems from the fact that when you use /r you are getting the full path and when you do not use the /r you are only getting the file name. Try this:
#echo off
setlocal enabledelayedexpansion enableextensions
for /r %%f in ("*[]*.*") do (
set oldname=%%f
set newname=!oldname:[]=!
call :NewFileNameOnly "!newname!"
echo !oldname!
echo !newname!
pause
ren "!oldname!" "!newname!"
)
goto :eof
:NewFileNameOnly
set newname=%~nx1
goto :eof

How to handle space of Filename in Batch For Loop

#echo off
echo processing please wait...
setlocal enabledelayedexpansion
set txtfile=%~dp0mysql\my.ini.bak
set newfile=%~dp0mysql\my.ini
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
set newline=%%a
echo !newline! >> %newfile%
)
Now my.ini.bak file is in D:\Program Files\my.ini.bak
Error : The system cannot find the file Files\mysql\my.ini.bak.
How to make this code work, so it copy each line from my.ini.bak to my.ini
The space in the path is indeed preventing FOR /F from opening the file successfully. You need quotes around the file name, but then you also need the FOR /F "USEBACKQ" option so that the quoted name is treated as a file name instead of a text string.
Using "TOKENS=*" is almost, but not quite the same as "DELIMS="
"DELIMS=" preserves the entire line
"TOKENS=*" preserves the remainder of the line after first stripping any leading spaces and/or tabs
I generally prefer "DELIMS=" unless I have a reason to strip leading spaces.
If there is a chance that the .INI file can contain ! character then you will want to toggle delayed expansion on and off within the loop. The value of %%a will be corrupted if it contains ! and delayed expansion is enabled.
It is more efficient to enclose the entire FOR loop within another set of parens and redirect the output just once instead of once for each iteration. It also eliminates the need to first delete the file if it already exists.
#echo off
echo processing please wait...
setlocal disableDelayedExpansion
set "txtfile=%~dp0mysql\my.ini.bak"
set "newfile=%~dp0mysql\my.ini"
>"%newfile%" (
for /f "usebackq delims=" %%a in ("%txtfile%") do (
set newline=%%a
setlocal enableDelayedExpansion
rem Presumably more processing goes here
echo !newline!
endlocal
)
)
I don't think you need to quote the paths, you can just use the short names in the expanded path. So use %~dps instead of %~dp
#echo off
echo processing please wait...
setlocal enabledelayedexpansion
set txtfile=%~dps0mysql\my.ini.bak
set newfile=%~dps0mysql\my.ini
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
set newline=%%a
echo !newline! >> %newfile%
)
By the way, the error I get with your original code is slightly different from your error, not sure why.
The system cannot find the file C:\Program.
The problem is the space in the file paths. I can't test this right now, but believe quoting the paths will fix it:
set txtfile="%~dp0mysql\my.ini.bak"
set newfile="%~dp0mysql\my.ini"
Here is the full code I tested with. For testing I added a space in "my sql" and created a folder by this name.
#echo off
echo processing please wait...
setlocal enabledelayedexpansion
set txtfile="%~dp0my sql\my.ini.bak"
echo %txtfile%
set newfile="%~dp0my sql\my.ini"
echo %newfile%
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
set newline=%%a
echo !newline! >> %newfile%
)

How can I edit this so it works with files that have spaces?

#echo off
set /A Counter=0
setlocal enabledelayedexpansion
for %%D in ("e:\test test\") do (
for /f %%F in ('dir /a-d /b %%D*.*') do (
ECHO.
ECHO Current file is: %%F
set src=%%F
set dest="e:\test test\space locate\%%F"
if not exist !dest! move !src! !dest!
if exist !dest! (
ECHO.
ECHO ERROR: "%%F" already exists
set /A Counter+=1
)
ECHO source file is !src!
ECHO destination is !dest!
)
)
echo.
echo %Counter% files not moved.
You probably just need to put quotes (") around all your filenames.
I'm talking about this sort of thing:
if not exist "!dest!" move "!src!" "!dest!"
That's just a suggestion, I don't have time to actually try to debug it right now.
Edit in response to comment:
for by default uses spaces as delimiters. You should say for /f "delims=" instead of just for /f in order to tell it not to do that.

Resources