【问题标题】:Script delete files in a folder and also tries to delete other files outside the folder脚本删除文件夹中的文件,并尝试删除文件夹外的其他文件
【发布时间】:2019-05-21 06:54:50
【问题描述】:

我使用批处理脚本删除脚本所在的本地文件夹中的一些文件。然而,该脚本试图删除位于其他位置(程序文件 (x86) 文件夹)的文件,这很可怕(希望这些文件受到读保护):我收到以下错误消息:

C:\Program Files (x86)\PathToFile\TimeSeries.DFSGenericBridge.dll 访问被拒绝
C:\Program Files (x86)\PathToFile\ClimateChange.DfsReader.dll 访问被拒绝
...

我认为 for 循环只是在脚本所在的文件夹内循环。

@echo off
Set exten=*.dfs*
for /f "delims=" %%F in ('Where /F %exten%') do (
       del %%F
    )
)

我希望脚本只尝试删除脚本文件所在文件夹中的文件。

如何避免这种副作用?

【问题讨论】:

    标签: batch-file


    【解决方案1】:

    您根本不需要where 来执行此操作,实际上我什至不建议使用 where。

    只需使用for /R,它将通过子目录从指定目录(脚本启动的地方)递归。

    @echo off
    set "exten=*.dfs*"
    for /R %%F in (%exten%) do (
       echo del "%%F"
    )
    

    但是,如果您只想从启动脚本的根目录中删除文件,而不是子目录:

    @echo off
    set "exten=*.dfs*"
    for %%F in (%exten%) do (
       echo del "%%F"
    )
    

    一旦您对屏幕上的输出感到满意,请删除 echo,它是作为故障保护添加的。将echo 添加到您的原始脚本也可以帮助您不删除您从未打算删除的文件,所以下次请考虑这样做。

    更多信息for命令,打开cmd.exe并运行:

    • for /?

    【讨论】:

      【解决方案2】:

      在您的情况下,for 循环将枚举来自where 输出的所有文件,而不管当前文件夹。跑吧

      where /f *.dfs*
      

      在命令行中,您会看到问题:where 正在显示驱动器上的所有文件。 如果要缩小范围,请使用/r 开关:

       /R       Recursively searches and displays the files that match the
                given pattern starting from the specified directory.
      

      【讨论】:

        【解决方案3】:

        鉴于您提供的代码和任务,要删除脚本所在的本地文件夹中的一些文件,我看不出有任何理由通过For 循环来实现这一点。 p>

        如果您只需要从包含正在运行的 的目录中删除扩展名为.dfs 的所有文件,您只需要一行命令:

        @Del /Q "%~dp0*.dfs"
        

        打开命令提示符窗口并输入 del /? 以读取其使用信息。

        使用返回的信息,如果您想从包含正在运行的脚本及其所有子目录的目录中删除任何扩展名以.dfs 开头的文件,那么您可以使用: p>

        @Del /Q /S "%~dp0*.dfs"
        

        【讨论】:

          【解决方案4】:

          where command 在搜索文件时也会考虑系统环境变量PATH 和PATHEXT。要将搜索限制在当前目录,从而忽略PATH,您需要添加前缀.:,如下所示:

          for /F "delims= eol=|" %%F in ('where ".:%exten%"') do (
              ECHO del "%%F"
          )
          

          但是,这仍然与 PATHEXT 相关,所以它也可以匹配 somefile.dfs.exe 之类的东西——不确定你是否想要那个……


          无论如何,更好的方法是直接使用for loop:

          for %%F in ("%exten%") do (
              ECHO del "%%~F"
          )
          

          或者您使用 dir command 代替:

          for /F "delims= eol=|" %%F in ('dir /B /A:-D "%exten%"') do (
              ECHO del "%%F"
          )
          

          但请注意,where 对待通配符的方式与 for 和 dir(它们是 cmd-internal 命令)并不完全相同,因为后者也考虑短 8.3 file names。

          有以下方法可以避免:

          1. 使用findstr 过滤输出或dir /B:

            set "FILTER=\.dfs"
            for /F "delims= eol=|" %%F in ('dir /B /A:-D "%exten%" ^| findstr /I /E /C:"%FILTER%"') do (
                ECHO del "%%F"
            )
            

            根据搜索条件,您可能需要将/R 选项添加到findstr。

          2. 使用where并暂时删除PATHEXT:

            set "PE=%PATHEXT%" & set "PATHEXT="
            for /F "delims= eol=|" %%F in ('where ".:%exten%"') do (
                ECHO del "%%F"
            )
            set "PATHEXT=%PE%"
            

            请注意,更改 PATHEXT 只会影响此 cmd 实例和潜在的子实例。

          测试输出后,去掉大写的ECHO,实际删除文件。

          【讨论】:

          • 您确定PATHEXT 与where 相关吗?据我所知不是。
          • 是的,@montonero;在当前目录下创建文件test.txt.exe并在其中执行where "test.txt"或where ".:test.txt"...
          • 你是对的,谢谢。我最初认为如果未指定文件扩展名,它只会使用PATHEXT。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-09
          • 1970-01-01
          • 1970-01-01
          • 2012-12-15
          • 1970-01-01
          相关资源
          最近更新 更多