根据平均文件大小将文件移动到子文件夹中 [英] Moving files into sub folders based by average filesize

查看:184
本文介绍了根据平均文件大小将文件移动到子文件夹中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编写批处理脚本或Powershell脚本时,我需要编程专家的帮助,该脚本将根据平均文件大小将一组文件从一个目录移动和划分为4个子目录.排序后,子目录的文件夹大小应大致相等.

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.

我为什么需要这个?

我想使用4台计算机通过FFMPEG进行编码,这对于脚本基于总平均大小将文件夹分为4个部分(子目录)会很有帮助.

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.

因此,可以说有各种各样的电影文件,它们具有不同的文件大小,总计100 GB,该脚本会将电影文件分为两部分,然后将它们移动到4个子文件夹中.每个文件夹大约有25 GB.这样做将使4台机器对数据之和进行均等有效的编码.

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.

在完成所有编码之后,我将拥有XYZ.(原始扩展名)和XYZ.264两个文件,可以比较这两个文件并删除较大文件的脚本将非常有帮助,并减少了手动检查的时间.

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.

推荐答案

@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
PUSHD "%sourcedir%"
:: number of subdirectories
SET /a parts=4
:: make subdirs and initialise totalsizes
FOR /L %%a IN (1,1,%parts%) DO MD "%destdir%\sub%%a" 2>nul&SET /a $%%a=0
:: directory of sourcefiles, sort in reverse-size order
FOR /f "tokens=1*delims=" %%a IN (
  'dir /b /a-d /o-s * '
 ) DO (
 REM find smallest subdir by size-transferred-in
 SET /a smallest=2000000000
 FOR /L %%p IN (1,1,%parts%) DO IF !$%%p! lss !smallest! SET /a smallest=!$%%p!&SET part=%%p
 REM transfer the file and count the size
 ECHO(MOVE "%%a" "%destdir%\sub!part!"
 REM divide by 100 as actual filelength possibly gt 2**31
 SET "size=%%~za"
 IF "!size:~0,-2!" equ "" (SET /a $!part!+=1) ELSE (SET /a $!part!=!size:~0,-2! + $!part!)
)
popd
GOTO :EOF

我相信这些言论应能解释该方法.原理是记录传输到每个子目录的长度,并选择填充最少的文件作为文件的目的地(以逆大小顺序处理)

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)

由于批处理的限制为2 ^ 31,因此我选择通过舍弃最后2位数字来将文件大小大致除以100.对于<100字节的文件,我任意地将其记录为100字节.

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.

您需要根据自己的情况更改sourcedirdestdir的设置.

You would need to change the settings of sourcedir and destdir to suit your circumstances.

所需的MOVE命令仅被ECHO用于测试目的. 确认命令正确无误后,将ECHO(MOVE更改为MOVE即可实际移动文件.附加>nul以禁止显示报告消息(例如1 file moved)

The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "destdir=U:\destdir"
SET "spaces=                             "
FOR /f "delims=" %%a IN (
  'dir /b /ad "%destdir%\*"'
  ) DO (
 PUSHD "%destdir%\%%a"
 FOR /f "delims=" %%f IN (
  'dir /b /a-d "*.xyz" 2^>nul'
  ) DO (
   IF EXIST "%%f.264" (
    FOR %%k IN ("%%f.264") DO (
     SET "sizexyz=%spaces%%%~zf"
     SET "size264=%spaces%%%~zk"
     IF "!sizexyz:~-15!" gtr "!size264:~-15!" (ECHO(DEL /F /Q "%%f") ELSE (ECHO(DEL /F /Q "%%f.264")
    )
   )
  )
 popd
)

GOTO :EOF

第二批将目录名称扫描到%%a中,然后通过命令切换到目标目录%destfile\%%a.

This second batch scans the directorynames into %%a then switches teporarily to the detination directory %destfile\%%a.

一旦找到,我们就会查找.xyz文件,并为找到的每个文件找到相应的.xyz.264文件.

Once there, we look for .xyz files and for each one found, find the corresponding .xyz.264 file.

如果存在,则我们找到文件的大小(%%~zk%%~zf),并将其附加到一长串空格中.通过将结果的最后15个字符作为字符串进行比较,我们可以确定哪个更长.

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.

所需的DEL命令仅被ECHO用于测试目的. 确认命令正确无误后,将ECHO(DEL更改为DEL以实际删除文件.

The required DEL commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(DEL to DEL to actually delete the files.

如果.264文件是filename.264而不是filename.xyz.264,则将每个 "%%f.264"替换为"%%~nf.264"(~n仅选择名称部分).

If the .264 file is filename.264 instead of filename.xyz.264 then replace each "%%f.264" with "%%~nf.264" (the ~n selects the name-part only).

要手动输入源目录名称,请使用

To manually enter a source directoryname, use

 SET /p "sourcedir=Source directory "

要接受源目录名称作为参数,请使用

To accept the source directoryname as a parameter, use

 SET "sourcedir=%%~1"

要处理除.h264文件以外的所有文件,请更改

To process all files, except .h264 files, change

 FOR /f "delims=" %%f IN (
  'dir /b /a-d "*.xyz" 2^>nul'
  ) DO (

 FOR /f "delims=" %%f IN (
  'dir /b /a-d "*.*" 2^>nul'
  ) DO if /i "%%~xf" neq ".h264" (

其中*.*表示所有文件",并且额外的if语句检查文件名%%f(%%~xf)的扩展名是否不等于(neq).h264,并且/i指示不管大小写(case- 不敏感)"

where *.* means "all files" and the extra if 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)"

这篇关于根据平均文件大小将文件移动到子文件夹中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆