batch-file - 批处理 - Ghost 文件通过 'If Not Exist' 检查

标签 batch-file file-exists not-exists

我的代码

下面是一些直接的代码:

  1. 检查目录中是否存在文件
  2. 运行 for 循环以获取第一个文件名
  3. 根据文件名做事
  4. 删除文件
  5. 检查目录中是否存在任何其他文件(如果存在,重复,如果不存在,继续)

    :MYLOOP
    IF NOT EXIST "%mypath%\*.*" GOTO nofile
    FOR %%F IN ("%mypath%\*.*") DO (
        set filenameWithExt=%%~nxF
        set filename=%%~nF
        set filepath=%%~pF
        )
    do other filename specific tasks
    
    del "%mypath%\%filenameWithExt%"
    
    IF NOT EXIST "%mypath%\*.*" GOTO nofile
    
    GOTO MYLOOP
    
    :nofile
    

我的问题

我反复使用了这段代码,它的效果非常好,但在我最近的使用中,它看起来像是在寻找一个“幽灵”文件。当目录中没有没有文件(只有一个存档文件夹)时,上面第 1 步中的if not exist 检查仍以某种方式通过。结果,for 循环中的 set 代码导致:

The system cannot find the file specified.

然后它似乎试图删除我的目录,说:

\\mypath*, Are you sure (Y/N)?

然后我必须手动终止否则自动批处理。

我的问题

为什么要通过 if not exist 检查,而不是跳到 :nofile?

我如何解释这个“幽灵”文件(或者如果它正在检测存档文件夹——我还能如何忽略它)?

最佳答案

Windows 内核和 Windows 命令解释器解释通配符模式 *.* 就像 * 一样,这意味着任何文件或文件夹。在使用通配符模式 *.* 时,并不意味着必须有名称中带有点的文件(或文件夹)。

因此,使用条件 IF NOT EXIST "%mypath%\*.*" 与使用 IF NOT EXIST "%mypath%\*" 相同.

IF EXIST "%mypath%\*" 通常用于批处理文件中以验证 %mypath% 指定的是文件夹而不是文件,因为此条件检查是否有一个文件夹 %mypath%。如果该文件夹存在,条件为,与该文件夹中的文件和文件夹数量无关。

所以批处理文件顶部的条件不会检查文件夹 %mypath% 中是否至少有 1 个文件,它会检查该文件夹是否根本不存在。

您可以使用以下批处理代码,通过子例程避免使用延迟扩展。

@echo off
for /F "delims=" %%I in ('dir /A-D /B /ON "%mypath%\*" 2^>nul') do call :ProcessFile "%mypath%\%%I"
goto :EOF

:ProcessFile
set "FilenNmeWithExt=%~nx1"
set "FileName=%~n1"
set "FilePath=%~p1"
rem do other filename specific tasks
del "%~1"
goto :EOF

命令FOR执行命令行

dir /A-D /B /ON "%mypath%\*" 2>nul

在后台的单独命令进程中,捕获写入处理 STDOUTDIR 的输出。

如果目录根本不存在或不包含任何文件,

DIR 将输出一条错误消息来处理 STDERR。通过使用 2>nul 将其重定向到设备 NUL 可以抑制此错误消息。重定向运算符 > 必须在此处使用脱字符 ^ 进行转义,以便 Windows 命令解释器在解析整个 FOR 命令时首先将其解释为文字字符行,否则会导致语法错误。

Option /A-D 表示 DIR 应该输出所有没有设置目录属性的目录条目,即只输出文件,不输出文件夹。 /BDIR 的输出更改为裸格式,这意味着只有文件名而没有任何其他数据。 /ON 导致在 DIR 输出整个列表之前按文件名对列表进行排序。此处实际上不需要此选项。

FOR 现在处理捕获的 DIR 输出。因此,在 FOR 运行时删除该目录中的文件并不重要。 FOR 将初始列表处理为 DIR 的输出。

对于 DIR 输出的每个文件名,执行子例程 ProcessFile,这就像调用另一个具有该名称的批处理文件。传递给子例程的是文件名及其路径。 DIR 仅输出不带路径的文件名,而不使用额外的 /S 来获取指定目录及其所有子目录中所有文件名的列表。

FOR 循环后的命令 goto :EOF 是为了避免在 DIR 输出所有文件名后跳转到子例程已处理。

如果上面的行是批处理文件的最后一行,则不需要子例程之后的命令 goto :EOF。但通常的好习惯是始终使用 goto :EOF 结束子例程,以防像下面的另一个子例程一样添加更多命令行。对于 Windows 命令解释器,以其标签开头的子例程在文件中的位置并不重要。

关于batch-file - 批处理 - Ghost 文件通过 'If Not Exist' 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44594728/

相关文章:

visual-studio-2010 - Visual Studio Post-Build 事件调用带有空格的参数的批处理文件

Python, subprocess, call(), check_call 和 returncode 来查找命令是否存在

php - 如何使 php file_exists 使用希腊字符

php - 使用file_exists并更新mysql行

batch-file - 获取批处理文件的完整路径

batch-file - 如何使用cmd从文本文件中删除第一行?

svn - 如何将 SVN 存储库热复制到现有位置?

python - 如果不存在则 SQLite 插入,否则增加整数值

php - 如果mysql查询没有结果则填写空白数据

sql - 如何使用 Access SQL VBA 在 where 子句中正确使用两个 Not Exists 语句?