2

How to move files to a folder until it reaches a certain size in Windows?

6
  • Move files from where?
    – and31415
    Aug 18, 2014 at 6:48
  • From another folder Aug 18, 2014 at 7:37
  • Whoever voted to close, care to explain? Aug 18, 2014 at 7:55
  • I didn't vote, but the question is lacking details IMHO. For example, where are those folder stored? Are there any subfolders in the source folder? If so, should those be processed too? Is the target folder empty or are there some files already? If the latter case, should files with identical names be skipped or overwritten? As for the size, what if it the target folder reaches a slightly bigger size? Would that be okay? What if the size can't be reached? Is the content of the source/target folders fixed before the move operation starts or can it change over time for other reasons?
    – and31415
    Aug 18, 2014 at 13:37
  • @and31415 These are details that don't really matter. The whole point is that the folder is of a certain size and the source could be from anywhere. If destination is slightly bigger, I can move from it. There won't be any same names. Dups are removed. OK if size can't be reached but the source has a lot more files. My question now is did you a solution and you weren't sure if it can meet the requirements or are all those questions out of curiosity and you really have nothing to offer?? Aug 18, 2014 at 16:16

2 Answers 2

1

Batch script

Here's a script which does just that. It has four parameters, the last one being optional: the source folder; the destination folder; the target size in bytes; the file extensions that should be matched. All parameters but the size require quotes.

@echo off
setlocal
setlocal enabledelayedexpansion

if "%~3" == "" exit /b 3
if "%~2" == "" exit /b 2
pushd "%~1" 2>nul || exit /b 4
pushd "%~2" 2>nul && popd || exit /b 5

set target=%~3
set /a target=%target:~0,-3% 2>nul || exit /b 6
set /a min=%target% / 1000

for /r "%~2" %%G in (*) do (
set size=%%~zG
set /a size=!size:~0,-3! 2>nul
if !errorlevel! equ 0 (
if !size! gtr !target! exit /b 7
set /a target -= !size!
))

if %target% leq %min% goto :end
set exts=* & if not "%~4" == "" set exts=%~4

for /f "delims=" %%G in ('dir %exts% /a:-d-h-s /b /o:-s 2^>nul') do (
if !target! leq %min% goto :end
set size=%%~zG
set /a size=!size:~0,-3! 2>nul
if !errorlevel! equ 0 if !size! leq !target! (
echo n 2>nul|move /-y "%%~fG" "%~2" >nul 2>&1 && set /a target -= !size!
))
:end
popd
endlocal & exit /b 0

How it works

The first lines ensure that the amount of parameters is correct. Each parameter is validated in order to reject non-existing folders and/or bad size values. To avoid integer overflow, the last 3 digits of the target size are truncated. A threshold value is set to 1/1000th of the target to provide some tolerance.

In order to account existing files, the content of the destination folder gets scanned and its total size gets computed. The resulting value is subtracted from the target size.

At this point the actual work begins: the source folder content is enumerated and sorted by file size, from biggest to smallest. Files get moved only when their size is less or equal to the current target, which is then updated. This greedy search continue until there are no more files or the minimum threshold is reached, whichever comes first.

Remarks

  • The command interpreter uses 32-bit signed integers to perform arithmetic operations, thus the highest positive value is 2^31 - 1 = 2147483647.

  • The target size can be any value (in bytes) between 1 KB and 2 TB.

  • Files with the Hidden or System attribute set are ignored.

  • In case the source folder contain one or more files which are already present in the destination folder, the move operation will be skipped to avoid potential data loss.

  • For performance reasons, the script used a cached value rather then enumerating files at every step to find the size of the destination folder. Files that get skipped because they share the same name will still add up to the total, and the resulting size can be skewed a result.

  • Subfolders aren't processed. If you need to, add the /s parameter to the dir command. Since the source structure gets flattened, you might end with identical named files that wouldn't be moved to the destination.

Further reading

0

With Powershell.

Do (the movement of the files from a folder to another) while (the size of the folder is not the desirable)

Use this demo on how to use the do while loop and change the echo script with the above scripts to fit your needs.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .