如何使用 Windows 批处理文件或 vbs 脚本一次将多个文件 1 从 2 个文件夹复制到另一个文件夹

Posted

技术标签:

【中文标题】如何使用 Windows 批处理文件或 vbs 脚本一次将多个文件 1 从 2 个文件夹复制到另一个文件夹【英文标题】:How could i copy multiple files 1 at a time from 2 folders to another folder with a windows batch file or vbs script 【发布时间】:2021-04-08 08:30:06 【问题描述】:

我正在使用摄像机,我们有一个程序可以在将 SD 卡插入 PC 时显示保存的视频。在某些时候,相机制造商更改了保存文件的目录结构和命名约定。我想创建一个批处理文件或 VBS 脚本,将文件重新组织成旧结构。对于基于 Windows 的 PC,这将是一个快速而肮脏的修复,直到我们可以重新编写将包括对 MAC 的支持的软件。它可以是批处理文件或 VBS 脚本,但必须在 Windows 命令提示符下运行,无需安装其他软件。摄像头有前置摄像头和后置摄像头,因此需要处理 2 个文件,并且可能需要重新定位 1 个或多个视频捕获。

文件夹的数量取决于保存的视频数量,假设保存了 4 个视频,那么原始结构如下所示。

- video1
    - video.TS
    - video2.TS
- video2
    - video.TS
    - video2.TS
- video3
    - video.TS
    - video2.TS
- video4
    - video.TS
    - video2.TS

新结构是这样的

- Normal
    - F
        - DATETIME-000001F.TS
        - DATETIME-000002F.TS
        - DATETIME-000003F.TS
        - DATETIME-000004F.TS
    - R
        - DATETIME-000001R.TS
        - DATETIME-000002R.TS
        - DATETIME-000003R.TS
        - DATETIME-000004R.TS

目标是将这些文件移动到较旧的文件结构中,以便软件可以读取和显示它们。我已经有一个在插入 SD 卡时运行的批处理文件,所以我的假设是我可以在正常进程触发之前包含一些脚本来移动这些文件。我对脚本很生疏,需要一些指导。

我当前的脚本如下所示。

setlocal enableextensions enabledelayedexpansion
set count=0
for %%x in (\Normal\F\*.TS) do (
set /a count += 1
mkdir video!count!
move /Y \Normal\F\*.TS \video!count!\video.TS
move /Y \Normal\R\*.TS \video!count!\video2.TS
)
endlocal

总是有2个视频,1个前置摄像头,1个后置摄像头,所以我只使用“F”目录来获取计数。

没有移动命令它创建目录结构就好了...如果有 1 个文件它只创建 1 个文件夹,如果有 8 个文件它创建 8 个文件夹。但是当有多个文件时,它希望将所有文件放在第一个文件夹中。 我假设我需要嵌套另一个循环,但我尝试过的一切都失败了,这是最接近的尝试。

【问题讨论】:

提示:%%x 是一次一个文件,因此您可以一次复制一个文件:move /Y "%%x" "video!count!\video.TS。为后部文件添加第二个循环(惰性方法)或使用子字符串操作(set /?)替换 \F` with \R` 并在同一循环中复制后部文件.. 【参考方案1】:
@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"


FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\normal\F\*-*.ts" '
 ) DO (
  SET "video2=%%~na"
  SET "video2=!video2:~0,-1!R%%~xa"
  FOR /f "tokens=2delims=.-" %%i IN ("%%a") DO (
   SET "video=%%i"
   SET /a video=1!video:~0,-1!-1000000
   MD "%destdir%\video!video!" 2>NUL
   MOVE /y "%sourcedir%\normal\F\%%a" "%destdir%\video!video!\video.TS" >NUL 2>nul
   MOVE /y "%sourcedir%\normal\R\!video2!" "%destdir%\video!video!\video2.TS" >NUL 2>nul

  )
 )
)

GOTO :EOF

您需要更改分配给sourcedirdestdir 的值以适应您的情况。该列表使用适合我的系统的设置。

我故意在名称中包含空格以确保正确处理空格。

首先,将在...\F 目录中找到的每个文件名分配给%%a

然后在...\R 中构造相应的文件名,方法是取%%a 的名称部分,删除最后一个字符并用R 替换它,然后附加%%a 的扩展名。

接下来,通过使用-. 作为分隔符从%%a 中选择第二个标记,从%%a 导出序列号。通过在 video 的最后一个字符前面加上 1 并减去 1000000 以将其转换为自然形式来设置目标目录名称的数字部分。

创建目标目录并移入并重命名源文件

[编辑以响应 cmets]

@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
SET "drives=d e f g h i j k l m n o p q r s t u v w x y z"
SET "sourcedir=normal"
:: locate drive that has directory "?:\normal\f"
FOR %%d IN (%drives%) DO IF EXIST "%%d:\%sourcedir%\f\." SET "sourcedir=%%d:\%sourcedir%"&SET "destdir=%%d:\video"&GOTO founddrive
ECHO Could not find "%sourcedir%\f" on any drive
GOTO :eof

:founddrive
SET /a destnum=1
FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\f\*-*.ts" '
 ) DO (
 MD "%destdir%!destnum!" 2>NUL
 SET "filename=%%~na"
 set "filename=!filename:~0,-1!R%%~xa"
 MOVE /y "%sourcedir%\F\%%a" "%destdir%!destnum!\video.TS" >NUL 2>nul
 MOVE /y "%sourcedir%\R\!filename!" "%destdir%!destnum!\video2.TS"  >NUL 2>nul
 SET /a destnum+=1
)

GOTO :EOF

好的,所以这个版本首先扫描目录名称,然后选择文件并将它们与名称更改一起放在同一驱动器上的目录video1... 中。

【讨论】:

感谢您在新年当天回复,这非常接近。我正在获取目录 video-888720 video-888735 video-888740 并且最后一个目录只有 1 个 TS 文件。它留在原来的 Normal\R 目录中,没有被复制。真的很想把它放在 video1 video2 video3 等中并包含最后一个文件 这些文件也将始终位于 SD 卡的根目录中,但我不知道驱动器号是什么,因为它可能在任何计算机中,我假设我可以不使用 %sourcedir% 和%destdir% 并且只使用 MD "\video!video!" 2>NUL 没有任何不良后果 好吧,这里是 1 月 2 日 - 凌晨 5 点左右...我无法解释为什么最后一个文件未能通过 move 指令 - 我能理解的唯一可能的解释是该文件当时是开放的。如果您从move 行中删除>nul 2>nul,则应生成一个报告以供筛选,这可能会产生线索。或者您可以复制move 行并将move /y 替换为echo 并删除now-echo 行的>nul 2>nul,它们分别抑制屏幕消息和错误消息到屏幕. 目录是完美的!最后一个文件是我的错,在 R 目录中我有 2 个具有相同时间/日期戳的文件。在我的测试中,我手动从另一个文件中复制了该文件。这在生产中永远不会发生。谢谢你的帮助。

以上是关于如何使用 Windows 批处理文件或 vbs 脚本一次将多个文件 1 从 2 个文件夹复制到另一个文件夹的主要内容,如果未能解决你的问题,请参考以下文章

如何让VBS文件 自动开机就运行

如何在Windows VBS Script上更改语音

CreateProcess 执行批处理文件

求一个让Windows应用程式置顶批处理或者VBS程序

如何让批处理执行完后停留在dos窗口

在后台模式下从 Nodejs 执行 VBS(任务计划程序或 Windows 服务)