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.
Related
First of all, I am a total beginner. I was trying an ultimate script bat file solution for a game. To not annoy you with details, let me tell you what I tried to do.
Example:
I have 17 files. 10 of them are .jpg and 7 of them are .obj files.
The images are in path \mods\images and the objects are in path \mods\models.
I want to list all 17 missing files in a list.txt
The bat file will read that list, search for the files and paste them into the TTSmissing folder
and here are my problems:
The bat script only looks exactly into the source path, but not into subfolders (that's why I wrote \mods\images\, to test if it works) so
what I basically want is: \Tabletop Simulator\Mods\ as source path and
the script shall look into all subfolders, too.
The list.txt only works, when the filenames also have their extensions. is it possible to change the script so i don't need the extension? so it will only look for names and copy the files? (example: the names in the list have to be like: hello123.jpg. It's not working when its only hello123.)
How do I need to change the bat script if i don't want a list.txt but just put the list of files right into the bat file?
#echo off
mkdir %USERPROFILE%\Desktop\TTSmissing
set src_folder=%USERPROFILE%\Documents\My Games\Tabletop Simulator\Mods\Images
set dst_folder=%USERPROFILE%\Desktop\TTSmissing
set file_list=%USERPROFILE%\Desktop\list.txt
for /f "tokens=*" %%i in (%file_list%) DO (
xcopy /S/E "%src_folder%\%%i" "%dst_folder%"
)
pause
#echo off
setlocal
set "src_folder=%USERPROFILE%\Documents\My Games\Tabletop Simulator\Mods"
set "dst_folder=%USERPROFILE%\Desktop\TTSmissing"
set "file_list=%USERPROFILE%\Desktop\list.txt"
set "ext_list=.gif .jpeg .jpg .mp4 .obj .pdf .png .webm"
if not exist "%dst_folder%" md "%dst_folder%"
for /d /r "%src_folder%\" %%A in (*) do (
pushd "%%~A" && (
for /f "usebackq delims=" %%B in ("%file_list%") do (
for %%C in (%ext_list%) do (
if exist "%%~B%%~C" (
echo copy /y "%%~B%%~C" "%dst_folder%\"
)
)
)
popd
)
)
You just want to copy files so copy is easier to use than xcopy. The code will echo the copy command to test whether it is working how you want it. If satisfied, remove the echo in front of copy and run the code again to do the actual copy process.
A for /d /r loop will recursively iterate the subdirectories in %src_folder%. pushd will change the current directory to each subdirectory so as can work relative to the source files.
The for /f loop will iterate each line from %file_list%. The simple for loop will iterate each of %ext_list%. If current "name.extension" exists, it will be copied to %dst_folder%.
If you set variables names in a script, it is usually a good idea to use setlocal to keep the variables defined local to the script.
To view help for a command, use command /?. This will work for many of commands used in the code.
View command /? help for copy, for, if, setlocal ...
I am trying to find specific files within a folder and its sub-folders and copy them to a new folder. I used to use this batch file for this purpose but now I get this error :
The system cannot find the file specified.
Here's the batch-file content:
pushd "\\internal.company.com\path\"
md myfile
FOR /R "\\internal.company.com\path\" %%G in (prefix_myfile*) do copy %%G "\\internal.company.com\path\myfile"
Any input is appreciated.
UPDATE
I tried printing %%G like this:
FOR /R "\\internal.company.com\path\" %%G in (prefix_myfile*) do echo %%G
and it works well. The problem arises with copy command which cannot read %%G as an argument.
I'd change to
... copy "%%G" ...
which would cater for spaces in %%G.
Perhaps you should determine whether the problem is with the for/r or %%G. If you simply display %%G with an echo %%G command, then you may see some problem. If it still won't run, then the for /r is the problem.
Since you are pushding to the appropriate directory, there is no need to specify the target directory in the for/r. It can be omitted or replaced by .
or perhaps echo %cd% directly after the pushd to show whether the pushd is the cause of the problem.
I realized that this would work for me (executed in cmd). However, it is plausible because I don't have any *.txt file in the main directory. Not the best solution but a workaround.
pushd "\\internal.company.com\path\"
rem first copy the desired files (text files) to the main-folder
for /f "tokens=*" %f in ('dir /a:-D /s /b myfile*') do copy "%f"
rem then make a new-folder and move them to there
md myfile
move *.txt "\\internal.company.com\path\myfile"
Note: if you want to execute this as a batch file, you need to use %%f instead of %f.
This will copy the files into main folder and then moves them into the desired sub-folder.
So I am trying to code an "A.I." through batch. The user will be able to enter in information, and the program will track keywords, and compile all data onto one text file in a specific folder. I have almost everything but a line that searches for all the filenames with a certain keyword. Here is an example. User: "Tell me EVERYTHING you know about GEORGE WASHINGTON" Program: Searches through memory for folder "George Washington" then gathers all the .txt files from that folder. It then types everything from those files to the user. Pls help, thanks :-)
you can do:
#echo off
set "foldertosearch=George Washington"
cd C:\
for /d /r %%a in ("%fodertosearch%") do (
echo found folder: %%a
cd %%a
)
for /f %%b in (*.txt) do (
echo found file: %%b
type "%%b"
)
pause
i recommend you to change the C:\ of the 3rd line to a specific folder because i am not shure the for /d loop can handle a whole drive. use the where command instead.
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.
I have a lot of (50 000+) files in a folder. They are named as: "abc_012345678_abcabc.ext"
I need to create a directory for each of this file (all in one different directory), named as the "number part" (012345678) and then copy this file to this directory.
So in the end, i have 50000+ directories, called like "265415873" , "654879623" and so on and inside each directory is the filename with matching name (so in dir 265478951 is file called abc_265478951_abcabc.ext).
Big thanks for any advice!
EDIT:
I already created a simple script, that does what I need, so if anyone is interested, here it is:
#ECHO OFF
setlocal enabledelayedexpansion
FOR %%f in (*.ext) DO (
set filename=%%f
set folder=!filename:~0,-4!
set copypath=e:\work\programy\adresare_handa\adresare\!folder!
mkdir !folder!
copy !filename! !copypath!
)
pause
In this case, I only delete the extension and use the whole name of the file for the name of the directory, but I know, how to alter it, to read just the part of the file I need.
Thanx a lot again, if anyone have any comment for my version (pros/cons), please, do enlighten me :)
Bye!
#echo off
pushd "C:\some_dir"
for /f "tokens=1,2,3 delims=_" %%A in ('dir /b /s /a-d') do (
md "%%~B"
copy %%A_%%B_%%C %%B
)
only in case all files are with name pattern like "abc_012345678_abcabc.ext"