我在删除特定大小以下的文件时使用以下批处理脚本。
@echo off
setlocal
:: Size is in bytes
set "min.size=100000"
for /f "usebackq delims=;" %%A in (`dir /b /A:-D *.*`) do If %%~zA LSS %min.size% del "%%A"
如果我将批处理文件放在文件夹中,这将有效,但它也会删除批处理文件。
但是,如何将批处理文件保存在不同的位置并明确指定目录路径?
我在删除特定大小以下的文件时使用以下批处理脚本。
@echo off
setlocal
:: Size is in bytes
set "min.size=100000"
for /f "usebackq delims=;" %%A in (`dir /b /A:-D *.*`) do If %%~zA LSS %min.size% del "%%A"
如果我将批处理文件放在文件夹中,这将有效,但它也会删除批处理文件。
但是,如何将批处理文件保存在不同的位置并明确指定目录路径?
最简单的解决方案是将要删除文件的目录设置为C:\Temp\Test临时活动目录。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Size is in bytes
set "min.size=100000"
set "FullBatchFileName=%~f0"
pushd "C:\Temp\Test"
rem Do nothing if the command line above fails unexpected.
if errorlevel 1 goto EndBatch
for /F "eol=| delims=" %%I in ('dir * /A-D-H /B /OS 2^>nul') do if not "%FullBatchFileName%" == "%%~fI" if %%~zI LSS %min.size% ( del "%%I" ) else goto DeletionDone
:DeletionDone
popd
:EndBatch
endlocal
DIR命令行由FORcmd.exe /C在后台启动的单独命令进程中执行,FOR捕获DIR输出的所有行以处理STDOUT。DIR在当前目录中找不到任何非隐藏文件时处理STDERR输出的错误消息被重定向2>nul到设备NUL以抑制它。
另请阅读有关使用命令重定向运算符的Microsoft 文章,了解2>nul. 当 Windows 命令解释器在执行命令FOR之前在后台启动的单独命令进程中执行嵌入式命令行时,重定向运算符>必须^在FOR命令行上使用脱字符进行转义,以将其解释为文字字符。dir
DIR选项导致获取由DIR/OS输出的非隐藏文件列表,按大小排序,最小的第一个和最大的最后一个。
FOR将跳过以分号开头的行,这意味着它将跳过文件名以;通常可能的文件开头的文件。这可以通过eol=|将竖线指定为文件名不能包含的行尾字符来避免。
FOR将使用普通空格和水平制表符作为分隔符将行拆分为子字符串,并且仅将第一个子字符串分配给循环变量I。文件名可以包含一个或多个空格。因此delims=用于定义一个空的分隔符列表,它完全禁用行拆分行为并将I整个文件名分配给循环变量。
IF条件将if not "%FullBatchFileName%" == "%%~fI"批处理文件的全限定名(驱动器 + 路径 + 名称 + 扩展名)与当前文件的全限定名进行比较,区分大小写。仅当当前文件不是当前运行的批处理文件时,此条件才成立。
下一个IF条件if %%~zI LSS %min.size%将转换为 32 位有符号整数的当前文件的文件大小与也转换为 32 位有符号整数的指定文件大小进行比较。此文件大小比较在 2 GiB或更大的文件上失败,因为这样的大文件超过了最大正 32 位有符号整数值 2147483647。
FOR循环在第一行退出,文件goto DeletionDone大小等于或大于指定的最小大小,因为DIR输出的所有其他文件的文件大小肯定等于或大于指定的最小大小,因为输出按大小从最小开始排序到最大。
要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
call /?... 解释%~f0... 参数 0 的完整限定文件名 - 当前执行的批处理文件。dir /?echo /?endlocal /?for /?goto /?if /?popd /?pushd /?rem /?set /?setlocal /?如果您想继续使用 PowerShell,以下脚本可能会起作用。如果您确信将删除正确的文件,请-WhatIf从Remove-Itemcmdlet 中删除 。
$deldir = 'C:\Temp'
$minsize = 100000
$precious = 'Remove-UnderSize.ps1', 'Remove-UnderSize.bat'
Get-ChildItem -File -Path $deldir |
ForEach-Object {
if (-not ($precious -contains $_.Name)) {
if ($_.Length -lt $minsize) {
Remove-Item -Path $_.FullName -WhatIf
}
}
}
可以从 cmd.exe bat 文件脚本调用此脚本。
powershell -NoProfile -File .\Remove-UnderSize.ps1