Batch Rename by Replace substring - batch-file

Hello :) when a friend give you a mp3 file, most often, the title is named that way: "avenged_sevenfold_-_buried_alive.mp3". i want to make a script which permit me to rename every file and folder of current repertoryby replacing "_" by " "(space). this is very long to rename each file manually; my script is here:
#echo off
title Merci qui ?
:debut
echo do you want to rename every files/foldes by replacing "_" by " "? (y/n)
set /p choix=
if %choix%==y (
goto renomage)
if %choix%==n (
goto end)
goto debut
:renomage
set /a x=1 :pointeur de fichier
set /a compteurA=0
set /a compteurB=0
for /f %%a in ('dir /b /a:-d *.*') do set /a compteurA+=1
for /f %%a in ('dir /b /a:d *.*') do set /a compteurB+=1
echo %compteurA% fichiers %compteurB% dossiers
set /a n=compteurA+compteurB
echo number of folder/files batch included %n%
:while1
if %x% GTR %n% goto prochain1
set Strin=???name?ofthe?dossier?number?x?????????????
for /f "tokens=1,* delims=[,]" %%A in ('"%comspec% /u /c echo:%Strin%|more|find /n /v """') do `set /a l=%%A-4`
echo Le nom contient %l% lettres.
:leftspace
set Strin=%Strin:_= %
set str=%Strin:~0,1%
if %str% EQU " "(
set Strin=%Strin:~1,%l%-1%
goto leftspace)
SET /A x +=1
goto while1
:prochain1
echo Success ! (or not)
pause
:end
i just need help for this line:
set Strin=???name?ofthe?dossier?number?x?????????????
otherwise the rest should be ok. if you have some critics or something, go on =)

This solution is reposted from How to Batch Rename Files in Windows: 4 Ways to Rename Multiple Files by Chris Hoffman
PowerShell offers much more flexibility for renaming files in a command-line environment. Using PowerShell, you can pipe the output of one command – known as a “commandlet” in PowerShell terms — to another command, just like you can on Linux and other UNIX-like systems.
First of all, open Powershell ISE and then navigate to the directory (folder) that has the files and folders you'd like to rename by using this command:
cd "C:\your\directory\"
The two important commands you’ll need are Dir, which lists the files in the current directory, and Rename-Item, which renames an item (a file, in this case). Pipe the output of Dir to Rename-Item and you’re in business.
After you launch PowerShell ISE, use the cd command to enter the directory containing your files. You should put the files in their own directory so you don’t accidentally rename other files.
For example, let’s say we don’t want the underscore character in our file names – we’d rather have a space instead.
The following command lists the files in the current directory and pipes the list to Rename-Item. Rename-Item replaces each underscore character with a space.
Dir | Rename-Item –NewName { $_.name –replace "_"," " }
Replace the "_" and "" parts of the command to replace other characters in file names.
Consult Microsoft’s documentation on the Rename-Item commandlet if you want help performing other, more advanced operations.

#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR %%f IN (ad a-d ) DO FOR /f "delims=" %%a IN (
'dir /b /s /%%f "%sourcedir%\*" '
) DO CALL :chgnam %%a
GOTO :EOF
:chgnam
SET "name=%*"
SET "newname=%name:_= %"
IF "%newname%" neq "%name%" ECHO REN "%name%" "%newname%"
GOTO :eof
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files and directories. Directories are renamed first.
You will need to change sourcedir to point to your required directory. All files and directories in the tree which contain the _ would be renamed - if it's possible to rename them.
[revised and corrected version]
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
PUSHD "%sourcedir%"
FOR %%f IN (ad a-d ) DO FOR /f "delims=" %%a IN (
'dir /b /s /%%f "%sourcedir%\*" '
) DO CALL :chgnam "%%a" "%%~nxa"
POPD
GOTO :EOF
:chgnam
SET "name=%~2"
SET "newname=%name:_-_=-%"
SET "newname=%newname:_= %"
IF "%newname%" neq "%name%" ECHO(REN "%~1" "%newname%"
GOTO :eof
The original version would show incorrect ren syntax (the new-name may not contain a path)
If you want to run on the current directory, simply set the value of sourcedir to a single dot.

Related

Copy, rename and move all files in directory

I have many pdf files I need to Copy, Rename and Move.
Copy and move works – I just can’t figure out how the rename part it’s done.
The files look like this:
2021-05-05_10-10-12-609_Testperson_Nancy_2512489996_19490816_OD_20210429112706.pdf
2021-06-05_11-11-12-135_Testperson_with_many _Names_0708681234_19490817_OD_20210429112715.pdf
and I need them to be renamed to:
251248-9996_19490816_OD_20210429112706.pdf
070868-1234_19490817_OD_20210429112715.pdf
So need to substring from the fourth _ from the right (without the first _) with a - between [6] and [7].
This is what I got so far:
SET input=c:\temp\rename\input
SET backup=c:\temp\rename\backup
SET output=c:\temp\rename\output
if not exist "%backup%" mkdir "%backup%"
for /f "tokens=*" %%F IN ('DIR /S /B "%input%\*.pdf"') DO (
xcopy /-y "%%F" "%backup%" & move "%%F" "%output%"
)
c:\temp\rename\input (for original files)
c:\temp\rename\backup (backup dir for orginal files)
c:\temp\rename\output (renamed files)
This must be run as a scheduled batch file job on Windows Server (I know how to run the job)
Give this a go. I would suggest you first make a backup of your files before running this in on your production files:
#echo off & setlocal enabledelayedexpansion
set "input=c:\temp\rename\input"
set "backup=c:\temp\rename\backup"
set "output=c:\temp\rename\output"
mkdir "%backup%">nul 2>&1
for /f "delims=" %%i in ('dir /b /s /a-d "%input%\*.pdf"') do (
set "cnt=-4"
set "_tmp=%%~i"
set "_tmp=!_tmp: =-!
set "_strip=!_tmp:_= !"
for %%c in (!_strip!) do (
set /a cnt+=1
)
if !cnt! gtr 1 if defined _tmp call :parser !cnt! "%%i"
)
goto :eof
:parser
for /f "tokens=%~1,* delims=_" %%a in ("%~2") do set "fin=%%~b"
echo xcopy /-y "%~2" "%backup%"
echo move "%~2" "%output%\%fin:~0,6%-%fin:~6%"
Some things to note. This does not yet do the actual copy or move, it will just echo the results, as a safety measure. So once you see it does what it should, then you can remove echo from the last two lines.
Lastly this is assuming the file format as you gave it, but it does cater for whitespace as well as double _ but it will go south if you have another _ separated section which does not form part of the standard format.
Demo
Given the 4 examples you gave in your question and comment (with the exception of the C:\tmp\Input in my example as I use a different directory to test):
You could probably do this easier using PowerShell, but to remain on topic, here's a batch-file which gets some assistance from powershell:
#Echo Off
SetLocal EnableExtensions
Set "input=C:\temp\rename\input"
Set "backup=C:\temp\rename\backup"
Set "output=C:\temp\rename\output"
For /F "Tokens=1-2 Delims=|" %%G In (
'%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile
"Get-ChildItem -LiteralPath '%input%' -Filter '*_*_*_*_*.pdf' -File | "
"ForEach-Object { $_.FullName + '|' + "
"(($_.Name).Split('_')[-4]).Insert(6,'-') + '_' + "
"(($_.Name).Split('_')[-3..-1] -Join('_')) }"') Do (
Echo=%SystemRoot%\System32\xcopy.exe "%%G" "%backup%\" && (
Echo=Move /Y "%%G" "%output%\%%H"))
Pause
Currently the script will just show you the commands it will run, if you're happy with the output, then delete Echo= from lines 12 and 13 and optionally the last line. As a side note, I used a trailing backward slash for the xcopy destination, this will cause %backup% to be created, if it does not already exist.

Creating a batch file to rename TXT files based on content (removing inappropriate syntax)

I am trying to create a batch file that will allow me to rename all files in a folder based on text located within the test file itself. I have pasted the first four lines from the text below:
09-Nov-16 07:50 AM HAND-HELD DRIVER REPORT PAGE: 1
XYZ COMPANY - AR1
DATE > 11/09/16 DRIVER > 1010 DRIVER NAME > Mike Smith TRUCK > 4719
I am trying to name each folder DATE-DRIVER NAME-TRUCK. I also need to drop the "/"'s in the date field. Any help would be incredibly appreciated!
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%x IN (
'dir /b /a-d "%sourcedir%\*.txt" '
) DO (
SET "oldname=%%x"
SET "newname="
SET "drivname="
REM detect a line with 4 ">"
REM Process only the first found in a file
FOR /f "usebackqtokens=1-5delims=>" %%a IN (
"%%x") DO IF NOT DEFINED newname IF "%%e" neq "" (
REM process date into %%i, %%j, %%k
FOR /f "tokens=1-3delims=/ " %%i IN ("%%b") DO (
REM build drivname
CALL :procname %%d
REM build new filename and rename file
CALL :build %%k %%i %%j %%e
)
IF NOT DEFINED newname ECHO %%x NOT renamed
)
)
GOTO :EOF
:procname
IF "%2"=="" GOTO :EOF
SET "drivname=%Drivname% %1"
shift
GOTO procname
:build
IF NOT DEFINED drivname GOTO :EOF
SET "newname=%1%2%3-%drivname:~1%-%4"
IF /i "%oldname%" neq "%newname%" (
ECHO(REN "%sourcedir%\%oldname%" "%newname%"
)
GOTO :eof
You would need to change the setting of sourcedir to suit your circumstances.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
Relatively simple:
Process each filename to %%x. With that filename, look for a line containing 4 > When that line is found (%%e will be non-empty) then the date will be in %%b, so parse it into %%i,j,k and process the name+TRUCK string in %%d. Finally, build the elements together - year in %%k, month in %%i, day in %%j, trucknumber in %%e and drivername in %drivname%.
The :build routine ensures that drivname exists and the builds the new filename from the supplied parameters and drivname. If the new and old names are the same (case-insensitive) then the rename would produce an error (file has already been processed previously) so skip the rename. Since newname is established in the :build routine, once a rename has happened, it won't be repeated.
Finally, if there was no newname set up, then the file hasn't got a line of the required format, so report that fact.
Here is my try, change BaseFld to fit your environment
#Echo off
Set BaseFld=Q:\Test\2016-11\10\
Set Files=*.txt
PushD %BaseFld%
For %%A in (%Files%) Do For /f "tokens=2-5 delims=>" %%B IN (
'findstr "DATE.*DRIVER.*DRIVER.NAME.*TRUCK" "%%~fA"'
) Do Call :Rename "%%~A" "%%B" "%%C" "%%D" "%%E"
PopD
Goto :Eof
:Rename
: Parse Date to yyMMdd
For /F "Tokens=1-3 Delims=/ " %%F in (%2) Do Set _YMD=%%H%%F%%G
For /F %%F in (%3) Do Set _DriverNo=%%F
Set _DriverName=%~4
Set _DriverName=%_DriverName: TRUCK=%
Set /A _TruckNo=%~5
Set "NewName=%_YMD%%_DriverName: =-%%_TruckNo%%~x1"
If /i "%~nx1" neq "%NewName%" Echo Ren %1 "%NewName%"
Result
Ren "Test.txt" "161109-Mike-Smith-4719.txt"
Edit To really rename the echo in the last line has to be removed. Included an if to prevent renaming an already processed file.

Search file with wildcard path

I want to write a script to prompt user for file path and list all files found. The file path can contain wildcards. Something similar to this. But the batch script version of it. For example:
C:\Somewhere\user*\app\version-*.*\start.exe
The files might be located like this:
C:\Somewhere\user345\app\version-1.0\start.exe
C:\Somewhere\user898\app\version-1.2\start.exe
C:\Somewhere\user898\app\version-1.3\start.exe
I tried to use FOR and it turns out to be so much harder than expected because FOR does not support wildcards in the middle of a path.
Is there a way to list these files? (Maybe without using for?)
I think this recursive solution works pretty well; you may name it WCDIR.bat:
#echo off
setlocal
if "%~1" neq "" set "next=%~1" & goto next
echo Show files selected by several wild-cards
echo/
echo WCDIR wildcardPath
echo/
echo Each folder in the path may contain wild-cards
echo the last part must be a file wild-card
goto :EOF
:next
for /F "tokens=1* delims=\" %%a in ("%next%") do set "this=%%a" & set "next=%%b"
if defined next (
for /D %%a in ("%this::=:\%") do (
setlocal
cd /D "%%~a" 2>NUL
if not errorlevel 1 call :next
endlocal
)
) else (
for /F "delims=" %%a in ('dir /B /A:-D "%this%" 2^>NUL') do echo %%~Fa
)
exit /B
EDIT: I fixed a small bug in the last for /F command.
For example, the output of WCDIR.bat C:\Windows\Sys*\find*.exe command in my Windows 8.1 64-bits computer is:
C:\Windows\System32\find.exe
C:\Windows\System32\findstr.exe
C:\Windows\SysWOW64\find.exe
C:\Windows\SysWOW64\findstr.exe
You can try with the command Where /?
The WHERE command is roughly equivalent to the UNIX 'which' command. By default, the search is done in the current directory and in the PATH.
#echo off
Where /R "%programfiles%" *winrar.exe
pause
#echo off
:: Example d'input
set UserInput=*drive*
:: building the Pattern
set cmd=%Userinput%.exe
:: storage Where.exe command in a macro, the execution will be faster
set whereCmd=where.exe /r c:\windows\ %cmd%
:: execution of macro and output formatting
for /f %%a in ('%whereCmd%') do echo %%~nxa --^> %%a
pause

copy & rename files to other folder

I have some of log files formatted like this "name.log"
I would like to copy those from one folder to another folder like
xcopy /y "C:\Folder1" "D:\Folder2"
And i need to rename file with created date of original file (no copy file) so that the text file in Folder2 would be like "name yyyymmddhhmm.log" if some file has the same name (date of creation) it will be overwritten.
The code:
set Source=C:\Users\user1\Desktop\Folder1
set Dest=D:\Folder2
if not exist %Dest% md %Dest%
for /F %%a in ('dir /b "%Source%\*.txt"') do call :Sub %%a
goto :eof
:Sub
set "filename=%1"
for /F %%s in ("%Source%\%1") do if %%~zs==0 goto :eof
set "datepart="
FOR /F "tokens=1-5 delims=/-: " %%a IN ('dir /tc "%filename%" ^| findstr "%filename%"') DO (
IF "%%c" neq "" SET "datepart=%%c%%a%%b%%d%%e"
)
FOR /F %%a IN ("%filename%") DO (
set "NewName=%%~na %datepart%%%~xa"
)
xcopy /y "%Source%\%filename%" "%Dest%\%NewName%*"
GOTO :EOF
The problem is that If I don't put the .bat in the same folder that origin files (Folder1),the files aren't change name. For example, if it is out, the files change name with old name and one white space.
The command windows tell me that it doesn't find the file when it get the creation date.
If I put the script into folder1 it works well.
On the other hand, if I execute the script with "Task Scheduler" I have the same problem. The files are copied but without date of creation.
What do I need to solve this problem?
#ECHO OFF
SETLOCAL
set Source=C:\Users\user1\Desktop\Folder1
set Dest=D:\Folder2
set "Source=u:\sourcedir\t w o"
set "Dest=u:\destdir"
if not exist "%Dest%" md "%Dest%"
for /F "delims=" %%k in ('dir /b "%Source%\*.log"') do call :Sub "%%k"
goto :eof
:Sub
SET "newname=%~1"
for /F "delims=" %%s in ("%Source%\%~1") do (if %%~zs==0 goto :eof
FOR /F "tokens=1-5 delims=/-: " %%a IN ('dir /tc "%Source%\%~1" ^| findstr "%~1"') DO (
IF "%%c" neq "" SET "newname=%%~ns %%c%%a%%b%%d%%e%%~xs"
)
)
ECHO(xcopy /y "%Source%\%~1" "%Dest%\%NewName%"
GOTO :EOF
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. Append >nul to suppress report messages (eg. 1 file copied)
This may seem quite a radical change, but actually it really isn't.
First issue is that I overrode your directory settings with directories to suit my system. The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. set /a can safely be used "quoteless".
Using quotes in the md command makes the procedure immune to "paths containing separators" - I test using spaces in paths and filenames because that appears to be a popular thing to do.
I changed the directory-scan metavariable from %%a to %%k to avoid confusion with the %%a in the subroutine. Your text says that you are starting with &.log files, but your filemask was *.txt so I changed it to *.log. Quoting the parameter delivered to :Sub means the procedure will receive the entire name of the file if it contains spaces.
Within the subroutine, it would appear that yowant no name-change if the %%c part from the dir/tc scan is empty. %~1 is the supplied filename minus the quotes.
The outer loop in %%s : I added delims= to cater for spaces in filenames and used %~1 in preference to %filename%
Within the %%s block, %%s refers to the file, so you can use %%s and its modified forms like %%~zs to refer to that file's characteristics - which unfortunately do not include create-date (%%~ts contains the last-update date - you may be able to use that in te following line rather than dir and findstr)
Then as #aschipfi suggested, include the source directory in the dir otherwise the dir takes place on the current directory.
FOR /F "tokens=1-5 delims=/-: " %%a IN ("%%~ts") DO (
should work for you if you can use last-update-date in place of create-date.
So - if %%c is not empty, set the new name to (the name part of the file in %%s)+space+the date string+(the extension in %%s)
And then do the xcopy - using the old name unless it was modified.

Rename A Sub-Directory the parent folder name if NOT called "info"

Is it possible to make a batch file that will rename a folder if does not have a specific name?
EG:
Parent Directory
- - - > info
- - - > randomfoldername
I have many folders that follow the above pattern. What I would like to do is make a batch file that will rename "randomfoldername" in this structure. There is always two folders in the Parent Directory, one is always "info" and the other changes for each case. Is there a method within a batch file that I could use to always rename the "randomfoldername" directory? I was thinking something along the lines of,
IF NOT == "info" THEN ren... ect.
Is this possible?
you can first check if folder exist then rename folder
if not exist c:\info ( call random.bat )
random.bat:
dir /A:D /b | findstr.exe /n /R "." > s:\sites\file-count.txt
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt"') do
set NUMBER-OF-FILES=%%A
FOR /L %%A IN (1,1,%number-of-files%) DO CALL RENAME.bat %%A
rename.bat
:rename
FOR /F "tokens=1-10 delims=:" %%A IN ('type "s:\sites\file-count.txt" ^|
findstr "%1:"') do ren %%B %RANDOM%%%B
also u can use free tool like Bulk Rename Utility
that app has cli for use in bat file here
also You can use powershell script like
$a = test-path c:\info
if ( $a -eq "True" ) { Write-Host nothing to do } Else { gic -directory path | %{$n="$pwd\$((get-random).tostring())$($_.name)";$_.moveto($N)} }
Next script starts with basic checks on command line parameter passed into.
FOR /F loop against the results of another command (dir) used. Next explanation stolen (see dbenham's original) :
FOR /R (as well as the simple FOR) begin iterating immediately, before
it has finished scanning the disk drive. It is possible for the loop
to reiterate the already named file! This would cause it to be renamed
twice, giving the wrong result. The solution is to use FOR /F with
command 'DIR /B', because FOR /F always processes the command to
completion before iterating.
#ECHO OFF >NUL
SETLOCAL enableextensions disabledelayedexpansion
set "ParentDirectory=%*"
if "%ParentDirectory%"=="" goto :usage1
if not exist "%ParentDirectory%\" goto :usage2
if not exist "%ParentDirectory%\info\" goto :usage3
set "SpecificName=Desired Name"
set /A "count=0"
for /F "delims=" %%G in ('dir /B /A:D "%ParentDirectory%\"') do set /A "count+=1"
if %count% neq 2 goto :usage4
for /F "delims=" %%G in ('dir /B /A:D "%ParentDirectory%\"') do (
if /I not "%%~G"=="info" (
if /I not "%%~G"=="%SpecificName%" (
echo renaming "%ParentDirectory%\%%~G" to "%SpecificName%"
rename "%ParentDirectory%\%%~G" "%SpecificName%"
) else (
echo renamed already: "%SpecificName%"
)
)
)
:endlocal
ENDLOCAL
goto :eof
:usage1
echo no paramater
goto :endlocal
:usage2
echo "%ParentDirectory%" folder does not exist
goto :endlocal
:usage3
echo "%ParentDirectory%\info" folder does not exist
goto :endlocal
:usage4
echo "%ParentDirectory%" folder contains %count% subfolders
goto :endlocal
Output:
==>29376745.bat
no paramater
==>29376745.bat x y
"x y" folder does not exist
==>29376745.bat d:\test
"d:\test\info" folder does not exist
==>md "d:\test\info"
==>29376745.bat d:\test
"d:\test" folder contains 6 subfolders
==>29376745.bat d:\test\29376745
renaming "d:\test\29376745\currentName" to "Desired Name"
==>29376745.bat d:\test\29376745
renamed already: "Desired Name"
==>
Required reading (indexes only):
An A-Z Index of the Windows CMD command line
Windows CMD Shell Command Line Syntax

Resources