Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 批处理脚本以删除目录中的所有其他文件_Batch File_File Io - Fatal编程技术网

Batch file 批处理脚本以删除目录中的所有其他文件

Batch file 批处理脚本以删除目录中的所有其他文件,batch-file,file-io,Batch File,File Io,我有一个包含数千个JPG的子目录。我想做的是创建一个批处理脚本,该脚本将遍历所有子目录并删除每个第二个图像,即保留第一个、第三个、第五个图像,但删除每个目录的第二个、第四个和第六个图像等(按文件名排序) 我尝试了以下方法,但我对批处理脚本的了解很差,而且语法显然不正确 @echo off set z = 0 for /f %%a in ('dir/b *.jpg') do ( set z = z + 1 if z == 2 del %%a ) DO必须与的在同一行上 如果你想做数学,

我有一个包含数千个JPG的子目录。我想做的是创建一个批处理脚本,该脚本将遍历所有子目录并删除每个第二个图像,即保留第一个、第三个、第五个图像,但删除每个目录的第二个、第四个和第六个图像等(按文件名排序)

我尝试了以下方法,但我对批处理脚本的了解很差,而且语法显然不正确

@echo off
set z = 0
for /f %%a in ('dir/b *.jpg')
do (
  set z = z + 1
  if z == 2 del %%a
)
  • DO必须与的在同一行上

  • 如果你想做数学,你必须使用SET/A

  • 你的逻辑是错误的-目前它只会删除第二个文件,而不是每隔一个。如果结果为0,则应取mod 2值(余数除以2)并删除

  • 如果要查看当前值(SET/a语句中的值除外),必须使用
    %z%
    。但这在只设置值的代码块中不起作用。在这种情况下,您需要启用延迟扩展并使用
    !z取而代之

  • 为包含
    的变量展开(在文件名中有效)将损坏该值。因此,必须打开和关闭延迟扩展

  • 您说希望递归子目录,但代码只查看一个文件夹

  • 空格在SET语句中很重要。您的代码定义了一个变量
    z
    ,该变量的名称末尾有一个空格。不是你想要的

以下是已调试的版本:

@echo off
setlocal
for /r %%D in (.) do (
  set "z=0"
  for /f %%F in ('dir /b "%%D\*.jpg"') do (
    set /a "z+=1, r=z%%2"
    setlocal enableDelayedExpansion
    if !r! equ 0 del "%%D\%%F"
    endlocal
  )
)
有很多方法可以解决这个问题,而不会延迟扩展。一种是简单地在定义变量和取消定义变量之间切换

@echo off
setlocal
for /r %%D in (.) do (
  set "del="
  for /f %%F in ('dir /b "%%D\*.jpg"') do if defined del (
    del "%%D\%%F"
    set "del="
  ) else set "del=1"
)
另一种方法是在要删除时故意除以0,并且仅在出现错误时才删除。
2>nul
隐藏错误消息,只有在先前的命令失败时,
|
操作符才有条件地执行以下命令

@echo off
setlocal
for /r %%D in (.) do (
  set "z=0"
  for /f %%F in ('dir /b "%%D\*.jpg"') do 2>nul set /a "z+=1, 1/(z%%2)" || del "%%D\%%F"
)

如果输出看起来不错,请尝试此操作并删除
echo

@echo off &setlocal
for /f "tokens=1*delims=:" %%a in ('dir /b /s /a-d *.jpg^|findstr /n $') do (
    echo %%a|findstr "[02468]$" >nul && echo del "%%~b"
)

使用dir/b,我认为它将只处理当前dir。如果我使用dir/b/s并在root中运行,它也会从所有子文件夹中删除第二个etc图像。@user2832776-是的。我允许自己受到您原始代码的影响。现在都修好了。FOR/R遍历目录树,每个目录的delete“flag”都会被重置。@LS\u dev-No,SET/A能够读取变量的值而无需展开-这是一个非常方便的功能。@LS\u dev-Oops,您在这一点上是正确的。都修好了。谢谢。这对我很有效,但是带空格的文件名不会被删除。我使用此脚本删除空格。它们能以某种方式合并吗+1个不错的脚本,但不会为每个子目录重置计数器。@LS\u dev显然不会。这不是必需的。这也没有意义,imo.:)如果有20个或更多的文件,这将给出错误的结果。顺便说一句,我认为整个任务毫无意义。但如果为每个文件夹重置计数,则会有显著差异。如果不重置,则以1个文件开头的文件夹可能最终没有文件,因此无法将其与以无文件开头的文件夹区分开来。如果重置每个文件夹,则以至少一个文件开头的每个文件夹将以至少一个文件结尾。缺点是,如果每个文件夹只有一个文件,则不会删除任何文件:)