I'm trying to write a Windows batch file to rename a set of files based on their original name. What I essentially want to do is find text within a file name and replace it with other text.
For example, if the files had the naming structure "Family Christmas 001.jpg" I might want to change it to "Photos - Xmas 001.jpg". ie replace "Family Christmas" with "Photos - Xmas". This is just an example.
I've found a piece of code from a user of this site, dbenham, that does almost exactly what I'm after. In this example he's replacing "120x90" in a filename to "67x100"
Here's the code:
#echo off
setlocal enableDelayedExpansion
for %%F in (*120x90.jpg) do (
set "name=%%F"
ren "!name!" "!name:120x90=67x100!"
)
Can anyone help me adapt this code to make it handle spaces in the file name?
Thanks
All you're missing is quotes within the FOR statement - to follow your example:
#echo off
setlocal enableDelayedExpansion
for %%F in ("Family Christmas*.jpg") do (
set "name=%%F"
ren "!name!" "!name:Family Christmas=Photos - Xmas!"
)
Related
this is my first Q on here, please forgive my ignorance in case I miss on best practices. I've reviewed prior requests to similar tasks, but couldn't apply their solutions to the situation described below.
This is about a CMD batch script to rename certain files only in a DIR and its SUBDIRs. All files share the same pattern:
FILENAME 0000.png
where 0000 is an arbitrary four digit number. Thanks to prior solutions here, I do have a working code for one DIR, alas, adding /r didn't make it recursive.
Below is a code snippet from my current CMD .bat (Win10 x64), removing /r works fine when renaming files in just one DIR only:
:dir_files_rename
SETLOCAL
SET "Path=G:\to\dir"
SETLOCAL enabledelayedexpansion
for /r %%f in ("%Path%\*.png") do if %%f neq %~nx0 (
set "filename=%%~nf"
echo %filename%
ren "%%f" "!filename:~0,-5!%%~xf"
)
ENDLOCAL enabledelayedexpansion
goto start
I don't have a method to identify and pass on exclusively files matching above pattern, because I can't come up such a method (doh!). Not elegant at all, because my code affects all files, but at least that's a start.
Cheers, BF
I need a batch file that renames my files in according to the folder name.
For example I have this folder:
E:\PROGET\01_Progetti\1_TRATTATIVE\IT.16.9291_Fabbricato ad Milano (MI) - Ing. Bianchi\03-CALCOLO\02-XLS\
Which contains
CB-Tech_92XX - .xls
Punz_92XX - .xls
I want to rename them to
CB-Tech_9291 - .xls
Punz_9291 - .xls
Is it possible?
EDIT:
I've found this code from a guy who asked for code and didn't get any complain Rename all files in a directory with a Windows batch script
I've changed it a little bit:
#echo off
setlocal enableDelayedExpansion
for %%F in (*92XX*) do (
set "name=%%F"
ren "!name!" "!name:92XX=9XXX!"
)
#pause
Now I just have to understand how to get the path (done), extract only the numbers (not yet) and store in a variable (done).
To set a variable should be something like that
set "number=projectnumber"
SET mypath=%~dp0
ok now I've the path, need to extract only 4 characters after the IT.16.
Will edit later :)
EDIT 2:
#echo off
setlocal enableDelayedExpansion
SET mypath=%~dp0
set projectnumber=%mypath:~41,4%
for %%F in (*92XX*) do (
set "name=%%F"
ren "!name!" "!name:92XX=%projectnumber:~0%!"
)
#pause
YEAH! This works for this specific folder!!
Now I just need to understand how to search and extract the number inside the path to make it more general.
I'm looking for a function that returns the position of the first char of the string IT.16.
Any advice?
This is the complete solution of this question:
#echo off
setlocal enableDelayedExpansion
SET mypath=%~dp0
set "projectnumber=%mypath:*IT.16.=%"
set "projectnumber=%projectnumber:~,4%"
for %%F in (*92XX*) do (
set "name=%%F"
ren "!name!" "!name:92XX=%projectnumber:~0%!"
)
I have many files in many folders that I need to rename.
And example is
from cgs2016-09-05-05-40-34.xls
to cgs0905.xls
and
from cgs2016-09-06-05-40-34
to cgs0906.xls
etc
Any help would be greatly appreciated!
#Jamaz Try out the following code below on a sample of your files. Again please use it on a test sample of your files so it does not cause you issues if it makes a mistake. Thank you and please up-vote if this works for you.
setlocal enabledelayedexpansion
REM Collect list of file names in current directory that have the .xls file extension. Output to text file.
dir /b "*.xls" >xls.txt
REM For loop examines the text file for individual file names.
FOR /F "tokens=1" %%# in (.\xls.txt) do (
REM SET variable "#" to equal "token"
Set "token=%%#"
REM Extract the first 3 characters (year) from the file name and set is to variable "token"
Set "tokenchar=!token:~0,3!"
REM Extract the month characters from the file name and set the variable as "tokenmonth"
Set "tokenmonth=!token:~8,2!"
REM Extract the day characters from the file name and set the variable as "tokenday"
Set "tokenday=!token:~11,2!"
ren "%%#" "!tokenchar!!tokenmonth!!tokenday!.xls"
echo %%#
)
Pause
not the best way, but works for your examples:
#echo off
setlocal enabledelayedexpansion
for %%x in (*.xls) do (
set "filename=%%x"
ECHO ren "%%x" "!filename:~0,3!!filename:~8,2!!filename:~11,2!.xls"
)
remove the ECHO if output is ok.
Because the last nineteen characters, date and time stamp, are more likely to be constant than the first three, (especially over multiple folders), I'd change both the previous answers to cater for that rationale.
#Echo Off
SetLocal EnableDelayedExpansion
(Set _rf=C:\Users\jamaz\TestDir)
(Set _fe=xls)
If Not Exist "%_rf%\" Exit/B
For /R "%_rf%" %%I In (*.%_fe%) Do (Set "_fn=%%~nI"
Echo=Ren "%%I" "!_fn:~,-19!!_fn:~-14,2!!_fn:~-11,2!%%~xI")
Timeout -1 1>Nul
EndLocal
Exit/B
As the OP was not clear about whether the code was for multiple same level folders or subfolders rooted from a single location, I went for the latter as the previous responses had already covered that.
Change your chosen file path and extension on lines 4 and 5
If you are happy with the console output, remove echo= from line 10 and delete line 11
I have hundreds of csv files . csv files are stored in folders and sub folders . I want to search fifty csv file whose file names have been determined , for example 1.csv , 2.csv , 3.csv , ... , 50.csv . very troublesome if I searched one by one using the Windows search tool . I would like if the files are found , save in the folder named FOUND . please help to overcome this problem by using the batch programming / bat ? thank you very much
There's a number of approaches one can take, depending on how much automation you require... To help you get started, you may want to look at this it helped me (and indeed continues to do so) when I started learning batch. Furthermore I will provide one possible template for achieving your objective, as I have interpreted it. Perhaps it is not the most elegant or efficient method, but it introduces a number of batch commands that you may or may not have encountered, which in turn may help you develop your own method.
#echo off
setlocal enabledelayedexpansion
echo Please enter a drive letter:
set /p "drive=>"
echo Please enter a search string:
set /p "searchstring=>"
echo %searchstring%>search.txt
set /p search=<search.txt
set /a suffix=0
echo.>>search.txt
:LOOP
for /f "tokens=*" %%i in ("search.txt") do (
set /a suffix=suffix+1
set seq=%search% !suffix!
echo !seq!>>search.txt
)
if !suffix! leq 49 goto LOOP
for /f "tokens=*" %%i in (search.txt) do (
for /f "tokens=*" %%j in ('dir /b /s /a-d %drive%:\"%%i.csv" 2^>nul') do (
if not exist "%~dp0\found" md "%~dp0\found"
move /y "%%j" "%~dp0\found\%%~nxj"
)
)
pause
This is not intended as a definitive solution, though you may find it answers your original query/request. All the best.
Here's another working solution for you..
#ECHO OFF
SETLOCAL EnableDelayedExpansion
REM First Set your directories input and output
SET InputDir=C:\Directory to your CSV files\
SET OutputDir=C:\Directory to your CSV files\FOUND
REM check if the FOUND directory exist, if not, then create it.
IF NOT EXIST OutputDir (
mkdir %OutputDir%
)
REM Grab a scan of the input directory and save it to a temporary file list.
Dir /a /b %InputDir%>"%OutputDir%\Found.txt"
REM Set the files you would like to find.
SET "File1=1.csv"
SET "File2=2.csv"
SET "File3=50.csv"
REM The loop, to process the matching file(s).
FOR %%A IN (%File1%,%File2%,%File3%) DO (
FOR /F "usebackq" %%B IN ("%OutputDir%\Found.txt") DO (
IF %%A==%%B (
copy "%InputDir%\%%A" "%OutputDir%\%%A"
)
)
)
REM Clean up the temp file list.
DEL "%OutputDir%\Found.txt"
Make note, I didn't add quotes to the Input and Output variables, but instead added quotes to the copy portion of the code to compensate for white spaces in your directory path. I tried to keep it simple, so you could follow the logic of how it processed what you are looking for, you can now modify this to your liking.. Have fun. Cheers!
I'm trying to get only one directory name out of a known path while searching for certain file types. In the example below I am searching for mp4 video files then I want to convert them and move them into a subdirectory of the same name in a different parent directory. The path is known up until the file's direct parent directory, so I was trying to remove the known part of the path. This is giving me a lot of trouble though. In the example below, the variable newDir is empty after the set command and it shows only an input of ~13 with #echo on. Can anyone tell me what I'm doing wrong?
Example:
setlocal enabledelayedexpansion
FOR /R %%X in ("*.mp4") DO (
set currDir="%%~pX" &REM "\test1\test2\dir1"
set newDir=%currDir:~13% &REM dir1
mkdir "C:\new\%newDir%" &REM suppose to be "C:\new\dir1", mine is just "C:\new\"
REM convert mp4 here
cp %%X "C:\new\%newDir%" &REM copies the file
)
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /R "%sourcedir%" %%a IN (*.mp4) DO (
FOR %%m IN ("%%~dpa.") DO ECHO(XCOPY "%%a" "c:\new\%%~nm\"
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required XCOPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(XCOPY to XCOPY to actually copy the files.
I note that you're using a very cygwinnish cp in place of copy. Be careful of nameclashes. I changed the command to xcopy in order that the destination directory can be automatically generated if required. Note that you haven't said what you want to do if the destination file already exists.
Here's a trial run on my test directory:
XCOPY "U:\sourcedir\misc\90s\ACDC - Back in Black.mp4" "c:\new\90s\"
XCOPY "U:\sourcedir\misc\90s\extended\Kelly Rowland - Wor! (Freemasons Arabic Mix).mp4" "c:\new\extended\"
XCOPY "U:\sourcedir\misc\90s\extended\Kelly Rowland - Work (Freemasons Arabic Mix).mp4" "c:\new\extended\"
XCOPY "U:\sourcedir\one\dummyfile1.mp4" "c:\new\one\"
XCOPY "U:\sourcedir\t w o\dum myfile2.mp4" "c:\new\t w o\"
XCOPY "U:\sourcedir\t w o\dum ile2.mp4" "c:\new\t w o\"
With enabledelayedexpansion in for loop, you should use !newDir! instead of %newDir%, and also !currDir:~13! instead of %currDir:~13% to make delayed expansion happen.
[update] There're also small errors. You should be careful about the spaces and quotes when you set to variables. They are actual part of the string to be set. And you have mkdir the same directory several times, and also it's better to user copy or xcopy instead of 'cp' which should be from "Cygwin" or "MinGW32" or something. xcopy will automatically create folders for you if not exist.
To make your codes work, please see below. And just a suggestion that you'd better learn more basic knowledge about bat before starting programming.
#echo off & setlocal enabledelayedexpansion
FOR /R %%X in ("*.mp4") DO (
set currDir=%%~pX
set newDir=!currDir:~13!
REM mkdir "C:\new\!newDir!"
REM convert mp4 here
xcopy "%%X" "C:\new\!newDir!"
)