通过指定目录删除文件

时间:2018-10-12 04:11:20

标签: windows batch-file cmd

我正在使用以下批处理脚本,同时删除了一定大小以下的文件。

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

如果我将批处理文件放在文件夹中,但它也删除了该批处理文件,这将起作用。

但是如何将批处理文件保留在其他位置并显式指定目录路径?

2 个答案:

答案 0 :(得分: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 命令行由 FOR 执行,该命令在以cmd.exe /C为背景的单独命令过程中执行,并且 FOR 捕获所有 DIR 输出的行以处理 STDOUT 。在发现当前目录中没有任何未隐藏文件的情况下, DIR 输出的用于处理 STDERR 的错误消息已通过2>nul重定向到设备 NUL 抑制它。

也请阅读有关Using Command Redirection Operators的Microsoft文章,以获取2>nul的解释。当Windows命令解释器在执行命令之前处理此命令行时,重定向操作符>必须在 FOR 命令行上使用脱字符号^进行转义,才能被解释为文字字符。 FOR ,它将在后台启动的单独命令进程中执行嵌入式dir命令行。

DIR 选项/OS导致获得 DIR 输出的未隐藏文件的列表,该列表按大小排在最前,最后排在最后。

FOR 将跳过以分号开头的行,这意味着它将跳过文件名以;开头的文件,通常这是可能的。通过使用eol=|将竖线指定为行尾字符(文件名不能包含)可以避免这种情况。

FOR 将使用普通空格和水平制表符作为分隔符将行分成子字符串,并且仅将第一个子字符串分配给循环变量I。文件名可以包含一个或多个空格。因此,delims=用于定义一个空的分隔符列表,这些分隔符将完全禁用行拆分行为,并被分配给循环变量I的整个文件名。

IF 条件if not "%FullBatchFileName%" == "%%~fI"将区分大小写的批处理文件的全限定名(驱动器+路径+名称+扩展名)与当前文件的全限定名进行比较。如果当前文件不是当前正在运行的批处理文件,则此条件仅 true

下一个 IF 条件if %%~zI LSS %min.size%将转换为32位带符号整数的当前文件的文件大小与也转换为32位带符号整数的指定文件大小进行比较。对于2个GiB或更大的文件,此文件大小比较失败,因为这样的大文件超过了最大正32位有符号整数值2147483647。

由于 DIR 输出的所有其他文件,在第一行的{strong> FOR 循环以第一行goto DeletionDone退出,该文件的大小等于或大于指定的最小大小。文件大小绝对等于或大于指定的最小大小,因为它是按大小从小到大的顺序输出的。

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /? ...说明%~f0 ...参数0的完全限定文件名-当前执行的批处理文件。
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • popd /?
  • pushd /?
  • rem /?
  • set /?
  • setlocal /?

答案 1 :(得分:1)

如果您想继续使用PowerShell,可以使用以下脚本。如果您确信将删除正确的文件,请从-WhatIf cmdlet中删除Remove-Item

$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