Reorder file name in folder with batch script - batch-file

I have many files that I would like to reorder the name of.
Currently the file names read as
XXX-YYYYY-ZZZ-A1B2C3
I would like to reorder A1B2C3 to ABC123.
XXX-YYYYY-ZZZ-ABC123
The XYZ portion of the string will be variable lengths for each file, the A1B2C3 will always be at the end of the string.
Being able to batch over all files in the current folder is a good starting point, and batching over all files in the current folder and all subdirectories would be even better.
Any help is much appreciated!

#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%f in ('dir /A-D /B *.*') do (
for /F "tokens=1-4 delims=-" %%a in ("%%~Nf") do (
set "last=%%d"
set "new=!last:~0,1!!last:~2,1!!last:~4,1!!last:~1,1!!last:~3,1!!last:~5,1!"
ECHO ren "%%f" "%%a-%%b-%%c-!new!%%~Xf"
)
)
Output example:
C:\> test.bat
ren "XXX-YYYYY-ZZZ-A1B2C3.ext" "XXX-YYYYY-ZZZ-ABC123.ext"
ren "XXX-YYYYY-ZZZ-X9Y8Z7.ext" "XXX-YYYYY-ZZZ-XYZ987.ext"
Some points about this code:
Your description say nothing about file extension so I assumed that the files have one. If not, just remove the %%~Xf part in the ECHO ren command.
The last command just show in the screen the REN commands. If the REN commands looks correct, remove the ECHO part in order to execute the REN. You may also duplicate this line in order to see the REN commands when they are executed.
To also process all subdirectories, add /S switch in DIR command this way: dir /A-D /B /S *.*
If you have also other files that don't needs renaming, you may select just these files changing the *.* wild-card in DIR command by *-*-*-*.*

You haven't mentioned which operating system you're using. I'll presume you're using *nix (Linux, OSX, BSD, etc); on Windows you could always install Perl and/or Cygwin.
Using the following rename script, you can write Regular Expressions to rename your files:
#!/usr/bin/perl -w
# rename - fix up file names
# examples:
# rename 's/\.orig$//' *.orig
# rename 'tr/A-Z/a-z/ unless /^Make/' *
# rename '$_ .= ".bad" *.f
$op = shift or die "Usage: rename expr [files]\n";
chomp(#ARGV = <STDIN>) unless #ARGV;
for (#ARGV)
{
$was = $_;
eval $op;
die $# if $#;
rename($was, $_) unless $was eq $_;
}
(Note: I didn't write this rename script - it's been kicking around the internet for years).
For example, to remove the XXX- from the start of all your files, you would do:
~/bin/rename 's/^XXX-//' *
The regex for renaming A1B2C3 to ABC123 is left as an exercise for the reader.

Related

Batch attachment of multiple .ttf files to a .mkv

Ok, I'm total new at this... Basically I'm using a tool call mkvmerge to attach multiple font files(.ttf) to .mkv files. I have separated the .mkv files into folders together with the respective fonts I would like to attach.
My aim is to create a batch that creates a copy of all the .mkv files with all the added attachments and deposits them in a newly created a folder (i.e Revised) in the parent directory.
Beginning with just a single folder:
mkdir Revised
for %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "%%~.ttf"
This works if I change the "%%~.ttf" to an actual .tff file name
(i.e
mkdir Revised
for %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "sans serif.ttf"
and I would end up with newly created Revised folder which contains a .mkv file with the sans serif.tff file attach within the .mkv file itself.
However I would like to add multiple .ttf files without naming them individually. (searching online it seems I need something like "$file" though I dont know how to use it)
Next if I have a parent folder with multiple sub-folders:
mkdir Revised
for /R %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "%%~.ttf"
This just flat out doesn't work. Not just because of the "%%~.ttf" issue I'm sure.
I know that it might be a bit too ambitious, so if some one could just help solve the first half of my problem, that would be lovely. Thanks a lot in advance.
Ps: If anyone need to understand the mkvmerge specific commands to help out: https://mkvtoolnix.download/doc/mkvmerge.html
Updates: For the first part
mkdir Revised
for %%x in (*.ttf) do (
for %%A in (*.mkv) do "%mkvmerge%" -q -o "Revised\%%A" "%%A" --attachment-mime-type application/x-truetype-font --attach-file "%%x"
)
It seems to work better but I think the script would now add and remove the the .ttf files until the last .ttf file in the folder remained.
Please give this a try. (Remember to set your %mkvmerge% variable to your executable path):
#echo off
set "mkvmerge=C:\Some Path\mkvmerge.exe"
for %%a in (*.ttf) do (
for /f %%i in ('dir /s /b /a-d *.mkv ^| findstr /vi Revised') do (
if not exist "%%~dpiRevised" mkdir "%%~dpi\Revised"
if not exist "%%~dpiRevised\%%~nxi" copy "%%~fi" "%%~dpiRevised"
"%mkvmerge%" -q -o "%%~dpiRevised\%%~ni_rev%%~xi" "%%~dpiRevised\%%~nxi" --attachment-mime-type application/x-truetype-font --attach-file "%%~dpi%%a"
)
)
So to explain what went wrong with your examples:
In the for loop, you take apply from the mkv inside the root folder, and apply a ttf file to it and create the new mkv file with the attached ttf to the Revised directory, then for the next ttf you again copy from the root directory, overwriting the mkv file in the Revised directory with a new one where a new ttf was applied etc.
Instead, we need to first make a copy of the mkv file into the Revised directory then we apply the first ttf file to itself in Revised and then take the mkv with the already attached ttf and apply another ttf to it until all ttf files have been applied to the new mkv inside of Revised The original mkv and all the ttf files will remain in the parent folder.
Note if any of what I explained does not make sense, let me know and I will rephrase.
I have decided to take a stab at this, it is intended to be run from the parent directory holding your directories, (I have assumed that those directories are all on the same level, this is not recursing through nested directories).
Please be aware that I am unable to test this.
#Echo Off
Set "mkvm=%UserProfile%\Downloads\Video Players, Editors, & Downloaders\MKVTool Batch Modifier\mkvmerge.exe"
For /F Delims^=^ EOL^= %%A In ('Dir/B/AD 2^>Nul^|FindStr/IVXC:"Revised"'
) Do If Exist "%%A\*.mkv" (If Exist "%%A\*.ttf" (
If Not Exist "Revised\" MD "Revised" 2>Nul||Exit /B
Call :S1 "%%A"))
GoTo :EOF
:S1
PushD %1 2>Nul||Exit /B
Set "as=--attachment-mime-type application/x-truetype-font --attach-file"
Set "ttfs="
For /F Delims^=^ EOL^= %%A In ('Where .:*.ttf'
) Do Call Set "ttfs=%%ttfs%% %as% "%%~nxA""
For /F Delims^=^ EOL^= %%A In ('Where .:*.mkv'
) Do "%mkvm%" -q -o "%~dp0Revised\%%~nxA" "%%~nxA" %ttfs%
PopD
I think I have also made this in such a way as to allow for more than one .mkv file in a directory, where each will be attached to all of the same .ttf files.
Get-ChildItem *.mkv | ForEach-Object {
$FontFlags = ""
Get-ChildItem -LiteralPath $_.BaseName -Exclude *.xml | ForEach-Object {
$FontFlags += " --add-attachment `"$($_.FullName)`""
}
Write-Host "Running &`"C:\Program Files\MKVToolNix\mkvpropedit.exe`" `"$_`" $FontFlags"
Invoke-Expression "&`"C:\Program Files\MKVToolNix\mkvpropedit.exe`" `"$_`" $FontFlags"
}
Read-Host "Press any key to exit..."
Make a folder with the same names as mkv without extension. Put mkv file, folder , this code in same folder and run it.
I didn't make this code. I asked someone to make this for my personal use.

Jump inside a 'FOR' loop within a BATCH file

Time ago I request some help to develope a short batch file to compress files inside a tree using 7zip, see following link:
Compress separately files within subfolders
Now I want to avoid already zipped files (.7z, .zip files) and jump to the next item.
Also I want to remove previous compressed files (like '.7z.7z' or '.zip.7z') created by using the original batch file several times on a same folder.
This is what I got so far:
#echo off
cd /d %~dp0
rem 7z.exe path
set sevenzip=
if "%sevenzip%"=="" if exist "%ProgramFiles(x86)%\7-zip\7z.exe" set sevenzip=%ProgramFiles(x86)%\7-zip\7z.exe
if "%sevenzip%"=="" if exist "%ProgramFiles%\7-zip\7z.exe" set sevenzip=%ProgramFiles%\7-zip\7z.exe
if "%sevenzip%"=="" echo 7-zip not found&pause&exit
#echo searching...
for /R %%I in (*) do (
if not exist %%I.zip if not exist %%I.7zip "%sevenzip%" a -mx -mmt4 "%%I.7z" -r -x!*.bat "%%I" && "%sevenzip%" t "%%I.7z" * -r
)
del "Compressing_files_7zip.bat.7z"
del *.7z.7z*
del *.zip.7z*
::::::::::::::::::::::::::For setting up shutdown 60' after the end of the process.Remove colons in the line below.
::shutdown.exe /s /t 3600
pause
The main issues I get with this code are:
-I am unable to detect already compressed files and therefore, jump to the next %%I entity.
-Remove non-desirable over-zipped files from sub-folders. Obviously, '*' wildcard does not work inside the loop; on the other hand, if I look for 'del %%I.7z.7z' it does not work either.
I read I cannot use a proper 'OR' fuction for the 'if' loops, that is why I nested them.
Thank you in advance.
Alex.
for /R %%I in (*) do (
if not exist %%I.zip if not exist %%I.7zip "%sevenzip%" a -mx -mmt4 "%%I.7z" -r -x!*.bat "%%I" && "%sevenzip%" t "%%I.7z" * -r
)
Note that %%I will contain the complete filename, so if you locate whatever.zip then the code looks for whatever.zip**.zip** or whatever.zip**.7zip** and will execute the 7zip if both of these are absent and generate whatever.zip**.7z**
so if you locate whichever.txt then the code looks for whichever.txt**.zip** or whichever.txt**.7zip** and will execute the 7zip if both of these are absent and generate whichever.txt**.7z**
I'd suggest
for /R %%I in (*) do (
if not exist %%~nI.zip if not exist %%~nI.7z "%sevenzip%" a -mx -mmt4 "%%~nI.7z" -r -x!*.bat "%%I" && "%sevenzip%" t "%%~nI.7z" * -r
)
which should select the name part only of the filename. (see for /?|more from the prompt for docco)
Hence, the code would look for whatever.zip or whatever.7z - finds whatever.zip and doesn't execute 7zip
or, for whichever.txt, the code would look for whichever.zip or whichever.7z - finds neither and executes 7zip generating whichever.7z
Now, since whichever.7z exists, further runs will skip the 7zip.
Which raises the question - if the zip/7z exists, why not try to freshen the archive, since the detected file may have changed?

Batch file to rename files by adding different suffix to each file

I want to create a batch file that will rename files from a folder my adding a different suffix to each file
An example would be like this,
file1.mp4
file2.mp4
file3.mkv
file4.mkv
to these
file1 sandwich.mp4
file2 hot dog.mp4
file3 apple.mkv
file4 toast.mkv
I am hoping to put all these words in the batch file but putting it in a separate txt file would be more preferable
Note: I will put the same number of suffix in the txt file as there are files on the folder.
I just want a faster way of adding these suffix than doing it one by one manually
I have limited knowledge about these codes
The program below rename the files in the order given by dir command with the suffixes given in suffixes.txt file. If there are more files than suffixes, the last suffix will be used several times.
#echo off
setlocal EnableDelayedExpansion
< suffixes.txt (
for /F "delims=" %%a in ('dir /B folder\*.*') do (
set /P suffix=
ECHO ren "%%~Fa" "%%~Na !suffix!%%~Xa"
)
)
For example:
C:\> type suffixes.txt
sandwich
hot dog
apple
toast
C:\> test.bat
ren "file1.mp4" "file1 sandwich.mp4"
ren "file2.mp4" "file2 hot dog.mp4"
ren "file3.mkv" "file3 apple.mkv"
ren "file4.mkv" "file4 toast.mkv"
If the ren commands looks correct, remove the ECHO part in the last command in order to execute the ren commands.

How to compress each subfolder in a folder into a separate RAR archive using WinRAR?

I am really new to batch file coding and need your help.
I've these directories:
c:\rar\temp1\xy.jpg
c:\rar\temp1\sd.jpg
c:\rar\temp1\dd.jpg
c:\rar\temp2\ss.jpg
c:\rar\temp2\aa.jpg
c:\rar\temp2\sd.jpg
c:\rar\temp3\pp.jpg
c:\rar\temp3\ll.jpg
c:\rar\temp3\kk.jpg
And I want to compress them to this
c:\rar\temp1\temp1.rar
c:\rar\temp2\temp2.rar
c:\rar\temp3\temp3.rar
How could this be done using WinRAR?
This can be done also with WinRAR without using a batch file, not exactly as requested, but similar to what is wanted.
Start WinRAR and navigate to folder c:\rar\.
Select the folders temp1, temp2 and temp3 and click on button Add in the toolbar.
As archive name specify now the folder for the RAR archives, for example c:\rar\.
Switch to tab Files and check there the option Put each file to separate archive.
Click on button OK.
WinRAR creates now three RAR archives with the file names temp1.rar, temp2.rar and temp3.rar in folder c:\rar\ with each archive containing the appropriate folder with all files and subfolders.
The list of files to add can be changed also on tab Files by entering for example *.txt in Files to exclude to ignore text files in the three folders on creating the archives.
And finally it makes sense to enter *.jpg on tab Files in edit field below Files to store without compression as JPEG files usually contain already compressed data and therefore WinRAR cannot really compress the data of the files further.
Here is also a batch file solution to move the files in all non-hidden subfolders of c:\rar\ and their subfolders into an archive file with name of the subfolder created in each subfolder as requested.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "RAREXE=Rar.exe"
if exist "%RAREXE%" goto CreateArchives
if exist "%ProgramFiles%\WinRAR\Rar.exe" set "RAREXE=%ProgramFiles%\WinRAR\Rar.exe" & goto CreateArchives
if exist "%ProgramFiles(x86)%\WinRAR\Rar.exe" set "RAREXE=%ProgramFiles(x86)%\WinRAR\Rar.exe" & goto CreateArchives
for /F "skip=2 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe query "HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe" /v Path 2^>nul') do (
if /I "%%I" == "Path" if exist "%%~K\Rar.exe" for %%L in ("%%~K\Rar.exe") do set "RAREXE=%%~fL" & goto CreateArchives
)
for /F "skip=2 tokens=1,2*" %%I in ('%SystemRoot%\System32\reg.exe query "HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe" /v Path 2^>nul') do (
if /I "%%I" == "Path" if exist "%%~K\Rar.exe" for %%L in ("%%~K\Rar.exe") do set "RAREXE=%%~fL" & goto CreateArchives
)
for /F "delims=" %%I in ('%SystemRoot%\System32\where.exe Rar.exe 2^>nul') do set "RAREXE=%%I" & goto CreateArchives
echo ERROR: Could not find Rar.exe!
echo/
echo Please define the variable RAREXE at top of the batch file
echo "%~f0"
echo with the full qualified file name of the executable Rar.exe.
echo/
pause
goto :EOF
:CreateArchives
set "Error="
for /D %%I in ("c:\rar\*") do (
echo Creating RAR archive for "%%I" ...
"%RAREXE%" m -# -cfg- -ep1 -idq -m3 -msgif;png;jpg;rar;zip -r -s- -tl -y -- "%%I\%%~nxI.rar" "%%I\"
if errorlevel 1 set "Error=1"
)
if defined Error echo/& pause
endlocal
The lines after set "RAREXE=Rar.exe" up to :CreateArchives can be omitted on definition of environment variable RAREXE with correct full qualified file name.
Please read the text file Rar.txt in the WinRAR program files folder for an explanation of RAR command m and the used switches. The question does not contain any information with which options the RAR archives should be created at all.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~f0 ... full name of batch file
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
reg /?
reg query /?
set /?
setlocal /?
where /?
See also single line with multiple commands using Windows batch file for an explanation of the operator &.
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on the three FOR command lines to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded reg or where command line with using a separate command process started in background.
This script can work as well:
#echo off
for %%a in ("C:\rar\temp1" "C:\rar\temp2" "C:\rar\temp3") do (
pushd "%%~a"
"C:\Program Files\WinRAR\rar.exe" a -r temp.rar *
popd
)
In Python v3.x:
Tested on Python v3.7
Tested on Windows 10 x64
import os
# NOTE: Script is disabled by default, uncomment final line to run for real.
base_dir = "E:\target_dir"
# base_dir = os.getcwd() # Uncomment this to run on the directory the script is in.
# Stage 1: Get list of directories to compress. Top level only.
sub_dirs_raw = [os.path.join(base_dir, o) for o in os.listdir(base_dir) if os.path.isdir(os.path.join(base_dir, o))]
# Stage 2: Allow us exclude directories we do not want (can omit this entire section if we wish).
dirs = []
for d in sub_dirs_raw:
if "legacy" in d or "legacy_old" in d:
continue # Skip unwanted directories
print(d)
dirs.append(d)
# Stage 3: Compress directories into .rar files.
for d in dirs:
os.chdir(d) # Change to target directory.
# Also adds 3% recovery record using "-rr3" switch.
cmd = f"\"C:\Program Files\\WinRAR\\rar.exe\" a -rr3 -r {d}.rar *"
print(cmd)
# Script is disabled by default, uncomment this next line to execute the command.
# os.system(cmd)
Notes:
Script will do nothing but print commands, unless the final line os.system(cmd) is uncommented by removing the leading # .
Run the script, it will print out the DOS commands that it will execute. When you are happy with the results, uncomment final line to run it for real.
Example: if there was a directory containing three folders mydir1, mydir2, mydir3, it would create three .rar files: mydir1.rar, mydir2.rar, mydir3.rar.
This demo code will skip directories with "legacy" and "legacy_old" in the name. You can update to add your own directories to skip.
To execute the script, install Python 3.x, paste the lines above into script.py, then run the DOS command python script.py from any directory. Set the target directory using the second line. Alternatively, run the script using PyCharm.
This should work it also checks if the files were compressed alright.
You may need to change this part "cd Program Files\WinRAR" depending on where winrar is installed.
#echo Off
Cd\
cd Program Files\WinRAR
rar a -r c:\rar\temp1\temp1.rar c:\rar\temp1\*.jpg c:\rar\temp1\
if "%ERRORLEVEL%"=="0" ( Echo Files compressed
) Else Echo Failed
rar a -r c:\rar\temp2\temp2.rar c:\rar\temp2\*.jpg c:\rar\temp2\
if "%ERRORLEVEL%"=="0" ( Echo Files compressed
) Else Echo Failed
rar a -r c:\rar\temp3\temp3.rar c:\rar\temp3\*.jpg c:\rar\temp3\
if "%ERRORLEVEL%"=="0" ( Echo Files compressed
) Else Echo Failed
Pause
Below Script will compress each folder as a RAR file within the current directory with very useful info while compressing a large size of data.
#echo off
#for /D %%I in (".\*") do echo started at %date% %time% compressing... "%%I" && #"%ProgramFiles%\WinRAR\Rar.exe" a -cfg- -ep1 -inul -m5 -r -- "%%I.rar" "%%I\"
echo "Completed Successfully !!!"
pause

How to bulk rename files within subfolders - using CMD command prompt

I am quite new to Command Prompt (Windows), however I have used it to do some file extensions changing and it is extremely helpful. I know nothing on coding, and so i am simply going off what I have read about but I am looking for a command line that I cant seem to find anywhere. I have folder, and inside that folder are 70 sub folders each labelled by a number from 1-70. Inside these subfolders are roughly 20 png picture files, that are currently numbered by a number from 1-20 in png format. I am looking for a command line to rename each file from its original name to "folder name (page number).png"
For example, I have folder called '68' and inside that folder is 1.png, 2.png, 3.png. I want the command line to change that 1.png and 2.png etc... to 68 (1).png and 68 (2). png, noticing the space between the bracket and the folder name. Sorry if i have made it confusing but I would really appreciate it and I have got some very helpful and quick answers from StackOverflow before
Thankyou if you are able to help me, as i am completely hopeless on this matter.
Only run this once - launch it from the folder containing the 70 folders.
#echo off
for /f "delims=" %%a in ('dir /ad /b') do (
pushd "%%a"
for /f "delims=" %%b in ('dir /a-d /b') do ren "%%b" "%%a (%%~nb)%%~xb"
popd
)
I am not a very experienced bash scriptor, but I guess this should do the task for you. I am assuming that you are using Linux operating system. So open a text editor and copy the following:
#!/bin/bash
NumberOfFolders=70
for((a=1; a <= NumberOfFolders ; a++))
do
cd ./$a
b=1
while [ -f $b.png ]
do
mv "$b.png" "$a($b).png"
let b=b+1
done
cd ..
done
save this script where you have you folders 1-70 (and call it whatever.ssh). Then open a terminal and write down chmod a+x whatever.ssh and after that ./whatever.ssh. This should do the job as you presented in your question.
A slight modification of the approach #foxidrive suggested, so the script can be run from anywhere and won't have to parse dir output:
#echo off
for /r "C:\root\folder" %%d in (.) do (
pushd "%%~fd"
for %%f in (*) do ren "%%~ff" "%%~nd (%%~nf)%%~xf"
popd
)
Note that this will not work in Windows XP (not sure about Windows Vista), due to a bug with the expansion of * in the inner for loop that would cause the files to be renamed multiple times.

Resources