Batch rename filename in subfolder - batch-file

What do I have to change here in this code so it could do also subfolders?
Or if it is easier to run only through subfolders?
#echo off
setlocal enableDelayedExpansion
for %%F in (*.jpg) do (
set "name=%%F"
ren "!name!" "!name:_=!"
)
This runs ok in current folder it erase in jpg filename character "_", but I don't know how to do it in subfolders, and that is my main goal to do.

It is possible to use a For /R loop:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /R . %%G In ("*_*.jpg") Do (
Set "name=%%~nxG"
SetLocal EnableDelayedExpansion
If Not Exist "%%~dpG!name:_=!" Ren "%%G" "!name:_=!"
EndLocal
)
I have used a . character after /R to signify the current directory as the recursion base, whilst this is not necessary, because the current directory is assumed if no path is provided, it serves as a reminder, the you could include another path there if needed.
Although you could also use a For /F loop, with the Dir command:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /F "EOL=? Delims=" %%G In ('Dir /B/S/A:-D "*_*.jpg"') Do (
Set "name=%%~nxG"
SetLocal EnableDelayedExpansion
If Not Exist "%%~dpG!name:_=!" Ren "%%G" "!name:_=!"
EndLocal
)
In this case, if you wanted to use a directory other than the current directory, you can insert it directly in the Dir glob, e.g. "C:\SomePath\*_*.jpg"
Please note however, in both cases, no attempt has been made to ensure that the remaining string, after removal of the underscores is a valid filename. It is your responsibility to incorporate such a check, if you wish to have robust code in your environment. Additionally no check is included to ensure that short filenames, (8.3), are not matched, so if this could be an issue in your target environments, then you should include modifications or additions to cater for that.

Related

Replace string in all file names in current folder and subfolders

I've been searching in forum but couldnt find the solution to my needs.
I have the following code to replace a defined string in filesname by extension. It is possible to change it to make the search in the current folder and subfolders please?
#echo off
Setlocal enabledelayedexpansion
Set "Pattern=3688"
Set "Replace=0000"
For %%a in (*.txt) Do (
Set "File=%%~a"
Ren "%%a" "!File:%Pattern%=%Replace%!"
)
Many thanks
You're close. Use for switch /R (for Recursive) and adapt to Set "File=%%~nxa" (because the second argument for ren does support a filename only - no path information)
#echo off
setlocal enabledelayedexpansion
Set "Pattern=3688"
Set "Replace=0000"
For /R %%a in (*.txt) Do (
Set "File=%%~nxa"
ECHO Ren "%%a" "!File:%Pattern%=%Replace%!"
)
It would make more sense, if you only loop through the ones containing your Pattern, instead of all of them, and only enabling delayed expansion, when needed.
Here's a complete example to show you:
#Set "Pattern=3688"
#Set "Replace=0000"
#For /R %%G In ("*%Pattern%*.txt") Do #(Set "BaseName=%%~nG"
SetLocal EnableDelayedExpansion
Ren "%%G" "!BaseName:%Pattern%=%Replace%!%%~xG"
EndLocal)
Please note however that this will not work with any string of characters defined as Pattern or Replace.

Loop through folder with files including a space

I want to loop through a folder and let run an algorithm on each .tif file found. Unfortunately this does not work for files which have a space character in their name. As my path already contains folders with space, i put the variable which stores the path name in double-quotation marks.
FOR /F %%k IN ('DIR /B "%mypath_import%"*.tif') DO (
SET infile=%%k
SET outfile=!infile:.tif=_UTM.tif!
REM ... do something
This is my attempt so far but it won't work for the files which include a space as well.
You done need all that. You can use the normal for loop without having to use /f
#echo off
setlocal enabledelayedexpansion
set "mypath_import=C:\Some path"
for %%i in ("%mypath_import%*.tif") do (
set "infile=%%~i"
echo "!infile:.tif=UTM.tif!"
)
The above will however echo full path to and file name, if you want filename only with extension:
#echo off
setlocal enabledelayedexpansion
set "mypath_import=C:\Some path"
for %%i in ("%mypath_import%*.tif") do (
set "infile=%%~nxi"
echo "!infile:.tif=UTM.tif!"
)
or without the need to delayedexpansion
#echo off
set "mypath_import=C:\Some path"
for %%i in ("%mypath_import%*.tif") do echo %%~dpni_UTM%%~xi
and again if you require the name and extension only.
#echo off
set "mypath_import=C:\Some path"
for %%i in ("%mypath_import%*.tif") do echo %%~ni_UTM%%~xi
EDIT
As per comment from #Stephan, keep in mind if you are doing actual renames and you run the script more than once it will keep on appending _UTM each time. So you'll get filename_UTM_UTM.tif etc. So you can exclude files from the loop by including findstr
for /f "delims=" %%i in ('dir /b *.tif ^|findstr /eiv "_UTM.tif"') do echo %%~ni_UTM%%~xi

In batch, how to check if dir names contains a substring while looping?

I would like to loop from current directory to the subdirectories and display only directories that does not contain a specific string (folder1 in this example):
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f "tokens=*" %%G in ('dir /b /s /a:d %cd%') do ^
set str1=%%G
if not x%str1:folder1=%==x%str1% echo %%G
endlocal
But, this script display nothing, yet I do have several subdirectories to go through.
Thank you for your help
Aurel
You almost done it:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f "tokens=*" %%G in ('dir /b /s /a:d') do (
set "str1=%%G"
if not "!str1:folder1=!" == "!str1!" echo %%G
)
endlocal
If you want the dir command show folders in current directory, just use dir /B /S /A:D; it is not necessary to include the %cd% part (in the same way that you type dir at the command-prompt, but not dir %cd%.
In set command it is convenient to enclose the variable and its value in quotes: set "str1=%%G"; this avoids problems caused by any non-visible space. The same apply for the values in if command.
When a variable is modified inside a for or if commands, the new value must be expanded via ! (that is the purpose of EnableDelayedExpansion).
The value of %%G replaceable parameter is valid only inside the for. Use parentheses to enclose all the commands that goes inside the for.

Rename files using batch file script

I want to rename the all PDF files in folder using batch script. for example i have 3 files in folder:-
anyfile.pdf
otherfile.pdf,
another.pdf
Now i want to rename file as bellow:-
PDF0.pdf
PDF1.pdf,
PDF2.pdf
i have fetch the files using this script:-
#ECHO OFF
SETLOCAL DisableDelayedExpansion
SET "r=%__CD__%"
FOR /R . %%F IN (*.pdf) DO (
SET "p=%%F"
SETLOCAL EnableDelayedExpansion
ECHO(!p:%r%=!
ENDLOCAL
)
pause
now i can rename please help me.
Thanks
Are you just looking for the command to rename files? Its ren. Look at http://ss64.com/nt/ren.html for more info.
FOR /R and the string replacement to get rid of the path seem unnecessary here, since you stay within one directory.
(generally, if you want to get of the path, just say %%~nxFwhich returns the Name and eXtension of %%F.)
you can perform arithmetics, ie. count a number up, with SET /A, so you could do simply
#ECHO OFF
setlocal enabledelayedexpansion
set i=0
FOR %%F IN (*.pdf) DO (
set /a i=i+1
ren %%F PDF!i!.pdf
)
pause

Batch: Rename multiple files using input string

I am trying to rename files after the user inputs a string they want to remove from the file name. This works fine except when I want to rename files that are in a different location than the script:
Here is what i have so far which works if I dont specific the file path (e.g. remove C:\DATABASE\*.* /s)
SET /P X=Type in the String that you want to remove and then press ENTER:
set deletestring=%X%
for /f "delims==" %%F in ('dir C:\DATABASE\*.* /s /b ^| find "%deletestring%"') do (
set oldfilename=%%F
set newfilename=!oldfilename:%deletestring%=!
Ren "!oldfilename!" "!newfilename!"
)
Thanks!
Use this instead. e.g.:
remove *.*
or
remove "relative path\*.*"
or
remove C:\DATABASE\*.*
or
remove "C:\My Database\2010-*.bak"
Meaning that a directory and file mask must be specified. Here's the remove.bat file:
#echo off
setlocal enabledelayedexpansion
set mask=%~1
set mask=!mask:%~dp1=!
if not exist "%~1" (
echo No files found
goto :eof
)
pushd "%~dp1"
SET /P X=Type in the String that you want to remove and then press ENTER:
set deletestring=%X%
for /f "delims==" %%F in ('dir "%mask%" /s /b ^| find "%deletestring%"') do (
set oldfilename=%%F
set newfilename=!oldfilename:%deletestring%=!
Ren "!oldfilename!" "!newfilename!"
)
Your primary problem you are running into is that the 1st argument to REN can accept full path info, but the 2nd can only contain the new name without path info. You can use the ~nx modifier to extract the name and extension from the full path reported by the FOR /F command.
Your FOR /F options are not reliable - it will break if the file name contains =. You want to set delims to nothing instead.
This problem is actually more complicated than it first looks. Your code will attempt to rename both files and directories. If you want to rename the directories then you must rename in reverse alpha order because the entire list is built before any thing is renamed. If you process in normal alpha order and rename a directory, then subsequent entries within that directory will not be found.
The FIND filter in the IN() clause is not necessary. Ideally your filter should only match the file or directory name, not the path. That is doable, but a bit tricky. I would simply skip the filtering in the IN() clause and do it in the DO clause.
A file or directory name can contain ! character. But the FOR variable expansion will be corrupted if it contains ! and delayed expansion is enabled. The problem can be avoided by toggling delayed expansion on and off within the loop.
It is possible for the entire name to be removed by the search and replace, but you cannot rename a file to nothing. So I added a test to ensure there is a name left.
setlocal disableDelayedExpansion
SET /P "X=Type in the String that you want to remove and then press ENTER:"
for /f "delims=" %%F in ('dir C:\DATABASE\* /s /b ^| sort /r') do (
set "old=%%F"
set "file=%%~nxF"
setlocal enableDelayedExpansion
set "new=!file:%X%=!"
if defined new if !new! neq !file! ren "!old!" "!new!"
endlocal
)
If you don't really want to rename directories then you need to add the /A-D option. I first thought you could use a FOR /R statement, but that could potentially cause the same file to be renamed twice. FOR /F buffers the entire result set before processing any files, but FOR /R does not.
setlocal disableDelayedExpansion
SET /P "X=Type in the String that you want to remove and then press ENTER:"
for /f "delims=" %%F in ('dir C:\DATABASE\* /s /b /a-d') do (
set "old=%%F"
set "file=%%~nxF"
setlocal enableDelayedExpansion
set "new=!file:%X%=!"
if defined new if !new! neq !file! ren "!old!" "!new!"
endlocal
)

Resources