I need the help of you programming savants in creating a batch script or powershell script that will move and divide a group of files from one directory into 4 subdirectories based on an average total filesize. After the sort, the sub-directories should be roughly equal in terms of folder size.
Why do I need this?
I have 4 computers that I would like to utilize for encoding via FFMPEG and it would be helpful for a script to divide a folder into 4 parts (sub-directories) based on a total average size.
So lets say there are an assortment of movie files with varying different file sizes totaling to 100 GB, the script would divy the movie files and move them into 4 sub folders; each folder having around 25 GB. Doing this will allow the 4 machines to encode the sum of the data equally and efficiently.
After all that encoding I'll have 2 files, XYZ.(original Extension) and XYZ.264, A script that could compare the 2 files and delete the larger file would be extremely helpful and cut down on manual inspection.
Thank you, I hope this is possible.
I believe the remarks should explain the method. The principle is to record the length-transferred to each subdirectory and select the least-filled as the destination for the file (processed in reverse-size order)
Since batch has a limit of 2^31, I chose to roughly divide the filesize by 100 by lopping of the last 2 digits. For files <100 bytes, I arbitrarily recorded that as 100 bytes.
You would need to change the settings of
sourcedir
anddestdir
to suit your circumstances.The required MOVE commands are merely
ECHO
ed for testing purposes. After you've verified that the commands are correct, changeECHO(MOVE
toMOVE
to actually move the files. Append>nul
to suppress report messages (eg.1 file moved
)This second batch scans the directorynames into
%%a
then switches teporarily to the detination directory%destfile\%%a
.Once there, we look for
.xyz
files and for each one found, find the corresponding.xyz.264
file.If that exists, then we find the sizes of the files (
%%~zk
or%%~zf
) and append that to a long string of spaces. By comparing the last 15 characters of the result as a string, we can determine which is longer.The required DEL commands are merely
ECHO
ed for testing purposes. After you've verified that the commands are correct, changeECHO(DEL
toDEL
to actually delete the files.If the
.264
file isfilename.264
instead offilename.xyz.264
then replace each"%%f.264"
with"%%~nf.264"
(the~n
selects the name-part only).To manually enter a source directoryname, use
To accept the source directoryname as a parameter, use
To process all files, except
.h264
files, changeto
where
*.*
means "all files" and the extraif
statement checks whether the extension to the filename%%f
(%%~xf
) is not equal to (neq
).h264
and the/i
directs "regardless of case (case-Insensitive)"Remember to keep the script file in a different directory when executing this. The script iterates over every file, so if the script was in the directory too it would be moved to one of the sub-directories.
This might seem like a simple request, but exact partitioning is actually a really hard problem.
The easiest way to approximate a somewhat fair partitioning is simply to sort all files (from biggest to smallest) and then distribute them one-by-one into n groups (a bit like if you were giving out cards for a card game):
If you have multiple file types that you want to include, use a
Where-Object
filter instead of theFilter
parameter withGet-ChildItem
: