How to delete all files from "Output" folder using batch script? - batch-file

I have a folder structure as below:
L:\MyProject\Extract\
Activity Input
**output**
SSIS
Results
Headers
Account Input
**output**
SSIS
Results
Headers
Balance Input
**output**
SSIS
Results
.
.
.
Here, I need to find output folder and delete all files present inside each "output" folder. I am using following script:
SET FolderPath=%1
for /f "usebackq" %%a in (`"dir %FolderPath% /ad/b/s output"`) do SET Folder="%%a"
del %Folder%\*.* /Q
But using above script, I am able to delete files which are present in "%%a"(last path of output folder). How to do it recursively...? Or is there any array concept to store all paths where output folder is present?

I see three problems in your code.
First, the for loop does not find the output subdirs under FolderPath, but iterates over all the subdirs of FolderPath.
One way to solve this is to specify
for /f "usebackq" %%a in (`dir "%FolderPath%\output" /ad/b/s`) do
Note that I have moved the quotes, just to prepare for the case of names with spaces, which was your second problem. You might further simplify it with
for /f "usebackq delims=" %%a in (`dir "%~1\output" /ad/b/s`) do
note that delims avoids spaces work as delimiters and %~1 removes the quotes of the parameter
And finally, the for loop, in each iteration, just sets the Folder variable, it does not invoke the del command, that is placed outside the loop.
One easy way to solve this problem is to invoke the del command on %%a without setting the variable folder
for /f "usebackq delims=" %%a in (`dir "%~1\output" /ad/b/s`) do del %%a\* /q

You could use the find command to find all subdirectories of the current directory.
To list files in all directories named Output:
find . -name Output -type d|find -type f -exec ls {} \;
To delete all files in directories named Output:
find . -name Output -type d|find -type f -exec rm {} \;

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.

Write checksum per folder

I'm trying to write a script that will run through a directory tree and generate a checksum for the contents of each folder and write the checksum to that folder; I've managed to do everything with the following code except write the checksum to the folder, it's currently writing everything to the root directory.
FOR /R "C:\_input\test" /D %%a IN (*) DO md5deep64 -r "%%a" >> "%%a.md5"
I thought I might be able to do something with the various modifiers (%~I) but no joy. Any ideas?
Based on your latest comment and my own, I think this may be what you want:
As a batch file:
#For /D %%A In ("C:\_input\test\*) Do #md5deep64 -r "%%A">"%%A.md5" & #Move /Y "%%A.md5" "%%A"
At the command line:
For /D %A In ("C:\_input\test\*) Do #md5deep64 -r "%A">"%A.md5" & #Move /Y "%A.md5" "%A"
Note that md5deep64.exe would need to be in the current directory or %Path%, otherwise you'd need to provide the full or relative path to it.

Find any file in directory/subdirectory and copy to new directory

I have a directory with a number of folders that each include sub-folders. I want to run a batch that searches those folders for the existence of a specific sub-folder called "failed". If there is a file present in this sub-folder, I want it to then move that file to another defined folder.
I've tried to look up usage of "if exist" commands but can't seem to find anything that directly suits my needs.
The names and types of the files to be moved are random, which is why I believed the "if exist" to be the most utile.
Any suggestion?
Read help for paying attention to the /r and /d options and then try this one-liner in the command line
for /d /r %a in (failed) do #echo %a
you will see that this loop iterates over all the directory structure and appends failed to the directory name
then add a check for the actual existence of the directory
if exist %a\nul #echo %a
then add a second loop to iterate over all of the contents of the found failed directory
for %b in (%a\*) do #echo %b
then replace the echo with the required move command
move %b %destination%\%~nxb
and there you go, with a simple single line
for /d /r %a in (failed) do #if exist %a\nul #for %b in (%a\*) do #move %b %destination%\%~nxb
or, translated into a bat file and spiced it up a bit
pushd %sourceroot%
for /d /r %%a in (failed) do (
if exist %%a\nul (
for %%b in (%%a\*) do (
move %%b %destination%\%%~nxb
)
)
)
popd
you'll have to figure out a way to rename the destination file to avoid name clashes.

Reorder file name in folder with batch script

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.

Batch: Copy files from txt file into one folder

I am attempting to create a batch file to copy several files listed in a text file to a new folder. I have found several threads relating to this, but I can still not get the batch to work properly. The problem I am encountering is that the files listed in the txt are all in different source locations and have different extensions. The list reads, for example:
C:\Users\Foo\Pictures\Photographs\September\P1030944.jpg
C:\Users\Foo\Videos\Art\Movies\Class\movie.avi
C:\Users\Foo\Music\Jazz\20051.mp3
...etc
All the copy commands I could find have to list either the source directory i.e.
set src_folder=c:\whatever\
set dst_folder=c:\foo
for /f %%i in (File-list.txt) DO xcopy /S/E/U "%src_folder%\%%i" "%dst_folder%"
or the extension i.e.
for /R c:\source %f in (*.xml) do copy "%f" x:\destination\
but I need it to gather that information from the list itself.
If it helps I know that there are only files of a possible 39 different specific extensions in the txt (*.jpg *.gif *.png ... *.xhtml *.xht)
Any help/ideas?
Start reading HELP FOR and then try the following at the command prompt
FOR /F %a in (input.txt) DO #ECHO COPY %a c:\newfolder\%~nxa
you can see that %a gets expanded to the actual line in the input file, and that %~nxa is a way to extract the name and the extension from the file.
After careful testing, move the command to your BAT file, replace %a to%%a, and remove the ECHO command
#echo off
SET destfolder=c:\newfolder
FOR /F "delims=" %%a IN (input.txt) DO COPY "%%a" "%destfolder%\%%~nxa"
notice the wraping of the names with quotes "; and the inclusion of the "delims=" option; both are needed in case filenames contain blanks.
Finally be careful with possible name duplicates in the destination folder. If that is possible, you need to find an strategy to cope with such collisions. But this can be the subject of another SO question, can't it?
One sample which worked for me...
Replace my directories C:\whatever and C:\temp\svn with yours...
assuming that your filelist is named antidump_list.txt and located under C:\temp\svn\
> set src_folder=C:\whatever
> set dst_folder=C:\temp\svn
> for /f %%i in (C:\temp\svn\antidump_list.txt) DO copy "%src_folder%\%%i" "%dst_folder%\%%i"
Regards,
Gottfried
I have found that the easiest way to do this is to use a powershell script.
$Files = Get-Content File-list.txt
$Dest = "C:\output"
foreach ($File in $Files) {
Copy-Item $File $Dest
}
If you need to run it from a batch file, paste the above script to file named CopyFiles.ps1 and add the following command to your batch file
powershell -executionpolicy bypass -file .\CopyFiles.ps1
Since, powershell is included by default on Windows7 and newer, this method is as easy as doing the same with batch commands only.

Resources