Batch file 如何使用批处理脚本复制文件而不知道该文件的完整路径?

Batch file 如何使用批处理脚本复制文件而不知道该文件的完整路径?,batch-file,Batch File,我想将文件从闪存驱动器E:\复制到本地计算机。但本地计算机上的文件夹结构如下所示: C:\Device\Number\One\xyz_01-01-19\Path\To\Folder C:\Device\Number\Two\xyz_01-02-19\Path\To\Folder C:\Device\Number\Three\xyz_01-03-19\Path\To\Folder C:\Device\Number\Four\xyz_01-04-19\Path\To\Folder 有数百个设备文件

我想将文件从闪存驱动器
E:\
复制到本地计算机。但本地计算机上的文件夹结构如下所示:

C:\Device\Number\One\xyz_01-01-19\Path\To\Folder
C:\Device\Number\Two\xyz_01-02-19\Path\To\Folder
C:\Device\Number\Three\xyz_01-03-19\Path\To\Folder
C:\Device\Number\Four\xyz_01-04-19\Path\To\Folder
有数百个设备文件夹,如
一个
两个
,等等。每个文件夹对设备都是唯一的,但所有子文件夹对每个单元都遵循相同的命名约定
xyz
是文件夹名称的固定起始部分,日期格式为
mm dd yy
附加在文件夹名称中

没有规则选择“自动按批处理脚本”将文件复制到用户选择的设备文件夹的变量日期相关子文件夹内具有已知路径的子文件夹中的设备文件夹。因此,批处理文件的用户必须输入设备文件夹名称。该文件应仅复制到用户确定的其中一个设备文件夹中

我遇到的一个问题是,文件夹路径中的日期与一个设备文件夹到下一个设备文件夹的日期不同。除日期外,其他所有内容都完全相同,我不知道如何在文件夹名中获得带有日期的文件夹名

我的脚本类似于以下内容:

REM Asking for the "Device" number
set /P device="Device Number?"
REM Copying files to the server
copy E:\log.pdf C:\Device\Number\%device%\xyz_01-01-19\Path\To\Folder

如果我正确理解您的问题+注释,这是您文件结构的第一部分(和问题部分):

C:.
└───Device
    └───Number
        ├───Four
        │   ├───xyz_1-1-19
        │   ├───xyz_1-2-19
        │   ├───xyz_1-3-19
        │   └───xyz_x-x-xx
        ├───One
        │   ├───xyz_1-1-19
        │   ├───xyz_1-2-19
        │   ├───xyz_1-3-19
        │   └───xyz_x-x-xx
        ├───Three
        │   ├───xyz_1-1-19
        │   ├───xyz_1-2-19
        │   ├───xyz_1-3-19
        │   └───xyz_x-x-xx
        └───Two
            ├───xyz_1-1-19
            ├───xyz_1-2-19
            ├───xyz_1-3-19
            └───xyz_x-x-xx
除非您始终知道选择要使用的
xyz_x-x-xx
文件夹所需的标准,否则您必须依靠人为决定。在这种情况下,您需要将用户输入添加到脚本中。下面是您应该如何实现这一点(在伪代码中):

以下是一些让您开始学习的读物:


以下批处理文件可用于此任务:

@echo off
if not exist "C:\Device\Number\" goto :EOF
setlocal EnableExtensions DisableDelayedExpansion

cls
echo Device folders in folder: "C:\Device\Number"
echo/
dir "C:\Device\Number\*" /AD /ON /W | %SystemRoot%\System32\findstr.exe /B /L /C:[
echo/

:PromptDevice
set "DeviceFolder="
set /P "DeviceFolder=Please enter device: "

rem Has the user not input any string?
if not defined DeviceFolder goto PromptDevice
rem Remove all double quotes from string value.
set "DeviceFolder=%DeviceFolder:"=%"
rem Has the user input just one or more double quotes?
if not defined DeviceFolder goto PromptDevice
rem If the user has input the device with [ at beginnning and with ] at end
rem as output by command DIR, remove those square brackets from device string.
if "%DeviceFolder:~0,1%" == "[" set "DeviceFolder=%DeviceFolder:~1%"
if not defined DeviceFolder goto PromptDevice
if "%DeviceFolder:~-1%" == "]" set "DeviceFolder=%DeviceFolder:~0,-1%"
if not defined DeviceFolder goto PromptDevice

rem Determine name of subfolder with date in name.
set "TargetFolder="
for /D %%I in ("C:\Device\Number\%DeviceFolder%\xyz_??-??-??") do set "TargetFolder=%%I\Path\To\Folder"

if not defined TargetFolder (
    echo/
    echo Subfolder xyz_??-??-?? not found in: "C:\Device\Number\%DeviceFolder%"
    echo/
    goto PromptDevice
)
if not exist "%TargetFolder%\" (
    echo/
    echo Folder "%TargetFolder%" not found.
    echo/
    goto PromptDevice
)

echo/
echo Copying log.pdf to "%TargetFolder%" ...
copy /Y /B "%~dp0log.pdf" "%TargetFolder%\"
echo/
endlocal
pause
初始检查文件夹
C:\Device\Number
是否存在后,使用DIR命令按名称以宽格式输出此文件夹中的所有子文件夹,并使用
FINDSTR
过滤掉DIR不以
[
,即页眉和页脚行。DIR还输出用户必须忽略的
[.]
[…]

然后,系统会提示用户输入设备编号文件夹的名称。请参阅,其中解释了附加的IF条件的原因,这些条件用于防止Windows command processor由于语法错误而意外退出批处理文件处理,否则,用户在输入设备文件夹时可能会出错我

如果输入了设备文件夹名称的文件夹确实存在,并且此设备文件夹包含一个与通配符模式匹配的非隐藏文件夹,则批处理文件使用命令FOR和选项
/D
获取带有日期的子文件夹的名称。否则,将通知用户缺少文件夹
xyz_???-
,并再次提示输入设备文件夹名称,因为用户输入的文件夹名称很可能不是100%正确

再次检查目标文件夹是否确实存在后,会通知用户文件复制,并通过批处理脚本复制该文件,希望复制成功。批处理文件希望该文件复制到包含用
%~dp0
引用的批处理文件的目录中,该目录始终扩展为以目录分隔符结尾的批处理字符串ator
\

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面

  • call/?
    …解释
    %~dp0
    …参数0的驱动器和路径,即完整批处理文件路径
  • cls/?
  • 复制/?
  • dir/?
  • echo/?
  • endlocal/?
  • findstr/?
  • goto/?
  • 如果/?
  • 暂停/?
  • rem/?
  • 设置/?
  • setlocal/?

另请参阅Microsoft文章about,了解重定向操作符

的解释,因此您正在尝试解析路径,如
C:\Device\Number\*\xyz \-??\path\to\Folder
?如果是,请使用嵌套,它允许为每个匹配的文件夹执行任务(如本例中的回音):
for/D%%J in(“C:\Device\Number\*”)在(“%%~J\xyz\u???-??”)中为/D%%I执行操作。执行echo/%%~I\Path\To\Folder
;从那里您可以获得更多信息,例如为设备文件夹的名称插入条件,如
如果“%%~nxJ”=“%Device%”echo设备文件夹:%%~J
。。。
@echo off
if not exist "C:\Device\Number\" goto :EOF
setlocal EnableExtensions DisableDelayedExpansion

cls
echo Device folders in folder: "C:\Device\Number"
echo/
dir "C:\Device\Number\*" /AD /ON /W | %SystemRoot%\System32\findstr.exe /B /L /C:[
echo/

:PromptDevice
set "DeviceFolder="
set /P "DeviceFolder=Please enter device: "

rem Has the user not input any string?
if not defined DeviceFolder goto PromptDevice
rem Remove all double quotes from string value.
set "DeviceFolder=%DeviceFolder:"=%"
rem Has the user input just one or more double quotes?
if not defined DeviceFolder goto PromptDevice
rem If the user has input the device with [ at beginnning and with ] at end
rem as output by command DIR, remove those square brackets from device string.
if "%DeviceFolder:~0,1%" == "[" set "DeviceFolder=%DeviceFolder:~1%"
if not defined DeviceFolder goto PromptDevice
if "%DeviceFolder:~-1%" == "]" set "DeviceFolder=%DeviceFolder:~0,-1%"
if not defined DeviceFolder goto PromptDevice

rem Determine name of subfolder with date in name.
set "TargetFolder="
for /D %%I in ("C:\Device\Number\%DeviceFolder%\xyz_??-??-??") do set "TargetFolder=%%I\Path\To\Folder"

if not defined TargetFolder (
    echo/
    echo Subfolder xyz_??-??-?? not found in: "C:\Device\Number\%DeviceFolder%"
    echo/
    goto PromptDevice
)
if not exist "%TargetFolder%\" (
    echo/
    echo Folder "%TargetFolder%" not found.
    echo/
    goto PromptDevice
)

echo/
echo Copying log.pdf to "%TargetFolder%" ...
copy /Y /B "%~dp0log.pdf" "%TargetFolder%\"
echo/
endlocal
pause