1

我在删除特定大小以下的文件时使用以下批处理脚本。

@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"

如果我将批处理文件放在文件夹中,这将有效,但它也会删除批处理文件。

但是,如何将批处理文件保存在不同的位置并明确指定目录路径?

4

2 回答 2

3

最简单的解决方案是将要删除文件的目录设置为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输出的所有行以处理STDOUTDIR在当前目录中找不到任何非隐藏文件时处理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 /?
于 2018-10-12T06:21:27.570 回答
1

如果您想继续使用 PowerShell,以下脚本可能会起作用。如果您确信将删除正确的文件,请-WhatIfRemove-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
于 2018-10-12T13:08:56.633 回答