批次腳本

批次腳本

在 Windows 中如何將檔案移至資料夾直到達到一定大小?

答案1

批次腳本

這是一個執行此操作的腳本。它有四個參數,最後一個是可選的:來源資料夾;目標資料夾;目標大小(以位元組為單位);應匹配的檔案副檔名。除大小外的所有參數都需要引號。

@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

怎麼運作的

第一行確保參數數量正確。每個參數都會經過驗證,以拒絕不存在的資料夾和/或錯誤的大小值。為了避免整數溢出,目標大小的最後 3 位將被截斷。閾值設定為目標的 1/1000 以提供一定的容差。

為了計算現有文件,將掃描目標資料夾的內容並計算其總大小。從目標大小中減去結果值。

此時,實際工作開始:枚舉來源資料夾內容並按檔案大小從最大到最小排序。只有當檔案大小小於或等於目前目標時,檔案才會被移動,然後更新。這貪心搜尋繼續,直到沒有更多文件或達到最小閾值(以先到者為準)。

評論

  • 命令解釋器使用32位有符號整數進行算術運算,因此最大正值為2^31 - 1 = 2147483647

  • 目標大小可以是 1 KB 到 2 TB 之間的任何值(以位元組為單位)。

  • 設定了隱藏或系統屬性的檔案將被忽略。

  • 如果來源資料夾包含目標資料夾中已存在的一個或多個文件,則將跳過移動操作以避免潛在的資料遺失。

  • 出於效能原因,該腳本使用快取值,而不是在每一步枚舉檔案來尋找目標資料夾的大小。由於共享相同名稱而被跳過的檔案仍然會累積到總數中,並且最終的大小可能會導致結果出現偏差。

  • 不處理子資料夾。如果需要,請將/s參數新增至dir命令中。由於來源結構變得扁平化,因此您可能會得到不會移動到目標的相同命名檔案。

進一步閱讀

答案2

使用 Powershell。

做 (將檔案從一個資料夾移動到另一個資料夾) 儘管 (資料夾的大小不理想

使用此示範介紹如何使用 do while 循環並使用上述腳本更改 echo 腳本以滿足您的需求。

相關內容