测试IF文件是否存在,删除这个本地文件

Test IF file exist, del this local file

此问题与有关。

背景: 有时我选择 运行 aGallery-dl.bat 在给定的文件夹(100 个文件夹中的每个文件夹中只有一个)。它首先删除 Folder.jpg,然后将 Folder2.jpg 重命名为 Folder.jpg。当查看在 文件资源管理器中选择父文件夹的文件夹时,红色 X 被黄色 ! 替换的效果。其次,它调用gallery-dl.exe。我使用从红色 X 到黄色 ! 来让我知道我至少有一次 运行 aGallery-dl.bat。如果 aGallery-dl.bat 成功完成,它最终会删除 Folder.jpg(当前为黄色 !),现在可以看到文件夹的代表性内容(通常是 DeviantArt .jpg) .一切顺利。

rem @echo off
del .\Folder.jpg
ren .\Folder2.jpg Folder.jpg
FOR /F %%i IN ('cd') DO set FOLDER=%%~nxi
"C:\Program Files (x86)\gallery-dl\gallery-dl.exe" -d "U:Web\gallery-dl" --download-archive ".\aGDB.sqlite3" "https://www.deviantart.com/"%FOLDER%"/gallery/all"
del .\Folder.jpg

问题: 重申一下,Gallery-dl.bat 在每个 100 个文件夹中。有时,我 运行 其中之一来自其本地文件夹。第 5 行,如果调用网站成功,gallery-dl.exe 在本地文件夹中创建 zzzGDB.sqlite3

在前面的代码中,当 aGallery-dl.bat 完成时,它只会删除 Folder.jpg假定对网页的调用成功。在极少数情况下,由于各种原因,对网页 的调用会失败 ,但在关闭时(由于最终 del .\Folder.jpg),它仍会删除 folder.jpg.

如果 zzzGDB.sqlite3 没有created/not存在,我需要Folder.jpg(黄色 !) 保留。

因此,在下面的代码中(第 6 行,现在为空),我删除了最后一个 del .\Folder.jpg 并尝试插入从第 7 行开始提供的代码,插入一个测试zzzGDB.sqlite。如果找到,del .\Folder.jpg。如果未找到,则不会对 folder.jpg 采取任何操作(它仍然存在)。
(最底部的 rem 语句只是作为我自己知识的占位符。)

rem @echo off
del .\Folder.jpg
ren .\Folder2.jpg Folder.jpg
FOR /F %%i IN ('cd') DO set FOLDER=%%~nxi
"C:\Program Files (x86)\gallery-dl\gallery-dl.exe" -d "U:Web\gallery-dl" --download-archive ".\zzzGDB.sqlite3" "https://www.deviantart.com/"%FOLDER%"/gallery/all"

setlocal EnableExtensions DisableDelayedExpansion
for /D %%I in ("U:Web\gallery-dl\deviantart\*") do (
    if exist "%%I\zzzGDB.sqlite3" (
        del "%%I\Folder.jpg"
    )
rem 
)
endlocal

注意: 目前,修改后的代码遍历 U:Web\gallery-dl\deviantart\* 中的每个文件夹。此操作应仅保留给本地文件夹。我猜下面是问题所在。

for /D %%I in ("U:Web\gallery-dl\deviantart\*")

我不知道如何删除它并在 do 之后仍然执行所有内容?

do (
if exist ".\zzzGDB.sqlite3" (
    del ".\Folder.jpg"
)
rem 
)

我建议对 aGallery-dl.bat 使用以下行。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0" || exit /B
move /Y "Folder2.jpg" "Folder.jpg"
for %%I in (.) do set "FOLDER=%%~nxI"
"%ProgramFiles(x86)%\gallery-dl\gallery-dl.exe" -d "U:Web\gallery-dl" --download-archive "%~dp0zzzGDB.sqlite3" "https://www.deviantart.com/%FOLDER%/gallery/all"
if not errorlevel 1 if exist "zzzGDB.sqlite3" del "Folder.jpg"
popd
endlocal

前两行定义批处理文件的执行环境。

命令PUSHD的第三行将当前目录路径压入堆栈,并将执行的批处理文件的目录设置为当前目录。这甚至适用于存储在使用 UNC 路径访问的网络资源上的批处理文件,除非在执行该命令行时出现网络问题。

命令exit /B在批处理文件目录不能设置为当前目录时出错立即退出批处理文件处理。在这种情况下,Windows 命令处理器隐式运行命令 ENDLOCAL

请参阅 Single line with multiple commands using Windows batch file 以了解运算符 || 的解释,它会导致有条件地执行 exit /B 仅当 pushd 以指示错误的非零退出代码退出时。

带有 MOVE 的第四个命令行并没有真正将文件 Folder2.jpg 的数据移动到名称为 Folder.jpg 的文件。实际上,在这种情况下,它只是更新文件系统,就像批处理文件中的两个命令 del .\Folder.jpgren .\Folder2.jpg Folder.jpg 一样。这只是用另一个文件替换一个文件的一种非常快的方法,其优点是 Folder.jpg 必须完全不存在才能成功,而不会像命令 DEL[=169 那样显示错误消息=] 文件 Folder.jpg 不存在。

FOR命令行判断当前文件夹的名称不带路径,赋给环境变量FOLDER。这是比使用命令行更快更安全的解决方案:

FOR /F %%i IN ('cd') DO set FOLDER=%%~nxi

上面的命令行导致在后台启动另一个命令进程,%ComSpec% /c' 之间的命令行附加为附加参数。所以在后台执行 Windows 安装到 C:\Windows:

C:\Windows\System32\cmd.exe /c cd

启动的cmd.exe执行内部命令cd输出当前目录的完整限定文件夹名称以处理后台命令进程的STDOUT。此输出由 cmd.exe 处理批处理文件捕获,并在启动后由 for 处理 cmd.exe 在完成命令 CD 执行后自行关闭。 =86=]

命令 FOR 会将文件夹路径拆分为子字符串(标记),使用普通 space 和水平制表符作为字符串分隔符,如果第一个 space/tab 分隔字符串以分号开头,在这种情况下,捕获的行将被忽略以进行进一步处理,否则只会将第一个 space/tab 分隔字符串分配给循环变量 i。因此,如果当前目录的完整限定文件夹名称包含 space,则此命令行将无法确定没有路径的当前目录的文件夹名称。

存在动态变量CD,其值可以用%CD%引用。该值是当前目录的完整限定文件夹名称 not 以反斜杠结尾,except 驱动器的根目录是当前目录。这与批处理文件 aGallery-dl.bat%~dp0 相同,不同之处在于 %~dp0 扩展为批处理文件夹的完整限定名称 always 带有反斜杠最后。

然而,无论是动态变量CD还是%~dp0或者在后台单独的命令进程中执行命令CD对于获取当前目录(=批处理文件目录)没有路径。最好的方法是使用:

for %%I in (.) do set "FOLDER=%%~nxI"

这个简单的 FOR 除了通过快速执行的文件系统查询获取没有路径的当前文件夹的名称并将其分配给环境变量 FOLDER。 =86=]

注意:如果当前目录不是批处理文件目录, for %%I in ("%~dp0.") do set "FOLDER=%%~nxI" 也可用于获取不包含当前执行的批处理文件的文件夹路径的文件夹名称.

第六行命令行执行gallery-dl.exe各种参数(arguments)

请注意 "https://www.deviantart.com/"%FOLDER%"/gallery/all" 实际上是一个无效的参数字符串。在 URL 中包含 " 是无效的。字符 " 在引用文件或文件夹的参数字符串中永远无效。此语法错误会被检测到并自动修复,这就是批处理文件中的命令行可以正常工作的原因。正确的参数字符串是 "https://www.deviantart.com/%FOLDER%/gallery/all",开头有一个 ",结尾有一个 ",并且参数字符串中没有双引号,用双引号引起来。

控制台应用程序的标准是在成功时以 0 值退出,在出错时以 1 等更大的值退出。我不知道 gallery-dl.exe 是否也是如此,但我假设使用命令行:

if not errorlevel 1 if exist "zzzGDB.sqlite3" del "Folder.jpg"

if not errorlevel 1 检查 如果 分配给动态变量 errorlevelgallery-dl.exe 的退出代码 不大于或等于 1 这意味着 小于 1 这意味着 等于 0 (在可执行文件上永远不会以负值退出,不建议任何操作系统上的程序执行此操作)这意味着 在执行 gallery-dl.exe 期间未发生错误 。请阅读有关此程序退出代码的 gallery-dl.exe 文档,或在命令提示符 window 中多次执行并在每次执行 gallery-dl.exe 后使用 echo Exit code is: %errorlevel% 找到它成功或错误(如错误 URL)。

这个条件应该已经足够了。但是在删除当前目录(批处理文件目录)中的文件Folder.jpg之前,还使用了一个条件来检查当前目录中是否存在文件zzzGDB.sqlite3

请阅读issue 2 in 因为写入批处理文件的原因

if not errorlevel 1 if exist "zzzGDB.sqlite3" del "Folder.jpg"

而不是

if not errorlevel 1 (
    if exist "zzzGDB.sqlite3" (
        del "Folder.jpg"
    )
)

上面的代码也可以工作,但是需要更多的 CPU 周期来被 Windows 命令处理器处理,而不是包含两个 IF 命令的单行和在一个命令行上执行一个 DEL 命令。

最后一行从堆栈中弹出初始当前目录的完整限定文件夹名称并将其再次设置为当前目录,最后一行在启动批处理文件时恢复初始执行环境。

为了了解使用的命令及其工作原理,请打开 command prompt window,执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • call /?... 说明 %~dp0 ... 参数 0 的驱动器和路径 ... 完整的批处理文件路径。
  • del /?
  • echo /?
  • endlocal /?
  • exit /?
  • for /?
  • move /?
  • popd /?
  • pushd /?
  • set /?
  • setlocal /?